Fix keyword arguments warnings in Active Job

Related #38053, #38187, #38105, #38260.

This is a reattempt to fix keyword arguments warnings in Active Job.

Now Ruby (master) has `Hash.ruby2_keywords_hash{?,}` and that will be
backported to 2.7.1.

https://github.com/ruby/ruby/pull/2818
https://bugs.ruby-lang.org/issues/16486

I've emulated that for 2.7.0 and older versions.
This commit is contained in:
Ryuta Kamizono 2020-01-19 11:35:55 +09:00
parent 99f18b618b
commit fc67857596
5 changed files with 47 additions and 4 deletions

View File

@ -52,6 +52,8 @@ module ActiveJob
# :nodoc:
SYMBOL_KEYS_KEY = "_aj_symbol_keys"
# :nodoc:
RUBY2_KEYWORDS_KEY = "_aj_ruby2_keywords"
# :nodoc:
WITH_INDIFFERENT_ACCESS_KEY = "_aj_hash_with_indifferent_access"
# :nodoc:
OBJECT_SERIALIZER_KEY = "_aj_serialized"
@ -60,10 +62,39 @@ module ActiveJob
RESERVED_KEYS = [
GLOBALID_KEY, GLOBALID_KEY.to_sym,
SYMBOL_KEYS_KEY, SYMBOL_KEYS_KEY.to_sym,
RUBY2_KEYWORDS_KEY, RUBY2_KEYWORDS_KEY.to_sym,
OBJECT_SERIALIZER_KEY, OBJECT_SERIALIZER_KEY.to_sym,
WITH_INDIFFERENT_ACCESS_KEY, WITH_INDIFFERENT_ACCESS_KEY.to_sym,
]
private_constant :PERMITTED_TYPES, :RESERVED_KEYS, :GLOBALID_KEY, :SYMBOL_KEYS_KEY, :WITH_INDIFFERENT_ACCESS_KEY
private_constant :PERMITTED_TYPES, :RESERVED_KEYS, :GLOBALID_KEY,
:SYMBOL_KEYS_KEY, :RUBY2_KEYWORDS_KEY, :WITH_INDIFFERENT_ACCESS_KEY
unless Hash.respond_to?(:ruby2_keywords_hash?) && Hash.respond_to?(:ruby2_keywords_hash)
using Module.new {
refine Hash do
class << Hash
if RUBY_VERSION >= "2.7"
def ruby2_keywords_hash?(hash)
!new(*[hash]).default.equal?(hash)
end
else
def ruby2_keywords_hash?(hash)
false
end
end
def ruby2_keywords_hash(hash)
_ruby2_keywords_hash(**hash)
end
private def _ruby2_keywords_hash(*args)
args.last
end
ruby2_keywords(:_ruby2_keywords_hash) if respond_to?(:ruby2_keywords, true)
end
end
}
end
def serialize_argument(argument)
case argument
@ -76,9 +107,14 @@ module ActiveJob
when ActiveSupport::HashWithIndifferentAccess
serialize_indifferent_hash(argument)
when Hash
symbol_keys = argument.each_key.grep(Symbol).map(&:to_s)
symbol_keys = argument.each_key.grep(Symbol).map!(&:to_s)
aj_hash_key = if Hash.ruby2_keywords_hash?(argument)
RUBY2_KEYWORDS_KEY
else
SYMBOL_KEYS_KEY
end
result = serialize_hash(argument)
result[SYMBOL_KEYS_KEY] = symbol_keys
result[aj_hash_key] = symbol_keys
result
when -> (arg) { arg.respond_to?(:permitted?) }
serialize_indifferent_hash(argument.to_h)
@ -132,6 +168,9 @@ module ActiveJob
result = result.with_indifferent_access
elsif symbol_keys = result.delete(SYMBOL_KEYS_KEY)
result = transform_symbol_keys(result, symbol_keys)
elsif symbol_keys = result.delete(RUBY2_KEYWORDS_KEY)
result = transform_symbol_keys(result, symbol_keys)
result = Hash.ruby2_keywords_hash(result)
end
result
end

View File

@ -86,6 +86,7 @@ module ActiveJob
@executions = 0
@exception_executions = {}
end
ruby2_keywords(:initialize) if respond_to?(:ruby2_keywords, true)
# Returns a hash with the job data that can safely be passed to the
# queuing adapter.

View File

@ -21,11 +21,13 @@ module ActiveJob
def perform_later(*args)
job_or_instantiate(*args).enqueue
end
ruby2_keywords(:perform_later) if respond_to?(:ruby2_keywords, true)
private
def job_or_instantiate(*args) # :doc:
args.first.is_a?(self) ? args.first : new(*args)
end
ruby2_keywords(:job_or_instantiate) if respond_to?(:ruby2_keywords, true)
end
# Enqueues the job to be performed by the queue adapter.

View File

@ -17,6 +17,7 @@ module ActiveJob
def perform_now(*args)
job_or_instantiate(*args).perform_now
end
ruby2_keywords(:perform_now) if respond_to?(:ruby2_keywords, true)
def execute(job_data) #:nodoc:
ActiveJob::Callbacks.run_callbacks(:execute) do

View File

@ -170,7 +170,7 @@ class ArgumentSerializationTest < ActiveSupport::TestCase
end
test "allows for keyword arguments" do
KwargsJob.perform_later(argument: 2)
KwargsJob.perform_now(argument: 2)
assert_equal "Job with argument: 2", JobBuffer.last_value
end