activesupport 7.0.8 → 7.2.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (199) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +142 -428
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +4 -4
  5. data/lib/active_support/actionable_error.rb +3 -1
  6. data/lib/active_support/array_inquirer.rb +3 -1
  7. data/lib/active_support/backtrace_cleaner.rb +39 -7
  8. data/lib/active_support/benchmarkable.rb +1 -0
  9. data/lib/active_support/broadcast_logger.rb +251 -0
  10. data/lib/active_support/builder.rb +1 -1
  11. data/lib/active_support/cache/coder.rb +153 -0
  12. data/lib/active_support/cache/entry.rb +134 -0
  13. data/lib/active_support/cache/file_store.rb +49 -17
  14. data/lib/active_support/cache/mem_cache_store.rb +94 -128
  15. data/lib/active_support/cache/memory_store.rb +80 -25
  16. data/lib/active_support/cache/null_store.rb +6 -0
  17. data/lib/active_support/cache/redis_cache_store.rb +165 -152
  18. data/lib/active_support/cache/serializer_with_fallback.rb +152 -0
  19. data/lib/active_support/cache/strategy/local_cache.rb +29 -14
  20. data/lib/active_support/cache.rb +363 -291
  21. data/lib/active_support/callbacks.rb +118 -134
  22. data/lib/active_support/code_generator.rb +15 -10
  23. data/lib/active_support/concern.rb +4 -2
  24. data/lib/active_support/concurrency/load_interlock_aware_monitor.rb +42 -3
  25. data/lib/active_support/concurrency/null_lock.rb +13 -0
  26. data/lib/active_support/configurable.rb +10 -0
  27. data/lib/active_support/core_ext/array/conversions.rb +1 -2
  28. data/lib/active_support/core_ext/array.rb +0 -1
  29. data/lib/active_support/core_ext/class/subclasses.rb +17 -34
  30. data/lib/active_support/core_ext/date/blank.rb +4 -0
  31. data/lib/active_support/core_ext/date/conversions.rb +1 -2
  32. data/lib/active_support/core_ext/date.rb +0 -1
  33. data/lib/active_support/core_ext/date_and_time/calculations.rb +10 -0
  34. data/lib/active_support/core_ext/date_and_time/compatibility.rb +28 -1
  35. data/lib/active_support/core_ext/date_time/blank.rb +4 -0
  36. data/lib/active_support/core_ext/date_time/conversions.rb +2 -2
  37. data/lib/active_support/core_ext/date_time.rb +0 -1
  38. data/lib/active_support/core_ext/digest/uuid.rb +7 -10
  39. data/lib/active_support/core_ext/enumerable.rb +3 -75
  40. data/lib/active_support/core_ext/erb/util.rb +201 -0
  41. data/lib/active_support/core_ext/hash/conversions.rb +1 -1
  42. data/lib/active_support/core_ext/hash/deep_merge.rb +22 -14
  43. data/lib/active_support/core_ext/hash/keys.rb +4 -4
  44. data/lib/active_support/core_ext/module/attr_internal.rb +17 -6
  45. data/lib/active_support/core_ext/module/attribute_accessors.rb +6 -0
  46. data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +34 -16
  47. data/lib/active_support/core_ext/module/concerning.rb +6 -6
  48. data/lib/active_support/core_ext/module/delegation.rb +20 -119
  49. data/lib/active_support/core_ext/module/deprecation.rb +12 -12
  50. data/lib/active_support/core_ext/module/introspection.rb +0 -1
  51. data/lib/active_support/core_ext/numeric/bytes.rb +9 -0
  52. data/lib/active_support/core_ext/numeric/conversions.rb +5 -3
  53. data/lib/active_support/core_ext/numeric.rb +0 -1
  54. data/lib/active_support/core_ext/object/blank.rb +45 -1
  55. data/lib/active_support/core_ext/object/deep_dup.rb +16 -0
  56. data/lib/active_support/core_ext/object/duplicable.rb +24 -15
  57. data/lib/active_support/core_ext/object/inclusion.rb +13 -5
  58. data/lib/active_support/core_ext/object/instance_variables.rb +4 -2
  59. data/lib/active_support/core_ext/object/json.rb +17 -7
  60. data/lib/active_support/core_ext/object/with.rb +46 -0
  61. data/lib/active_support/core_ext/object/with_options.rb +4 -4
  62. data/lib/active_support/core_ext/object.rb +1 -0
  63. data/lib/active_support/core_ext/pathname/blank.rb +20 -0
  64. data/lib/active_support/core_ext/pathname/existence.rb +2 -0
  65. data/lib/active_support/core_ext/pathname.rb +1 -0
  66. data/lib/active_support/core_ext/range/conversions.rb +28 -7
  67. data/lib/active_support/core_ext/range/overlap.rb +40 -0
  68. data/lib/active_support/core_ext/range.rb +1 -2
  69. data/lib/active_support/core_ext/securerandom.rb +1 -5
  70. data/lib/active_support/core_ext/string/conversions.rb +1 -1
  71. data/lib/active_support/core_ext/string/filters.rb +21 -15
  72. data/lib/active_support/core_ext/string/indent.rb +1 -1
  73. data/lib/active_support/core_ext/string/inflections.rb +16 -5
  74. data/lib/active_support/core_ext/string/multibyte.rb +1 -1
  75. data/lib/active_support/core_ext/string/output_safety.rb +34 -177
  76. data/lib/active_support/core_ext/thread/backtrace/location.rb +12 -0
  77. data/lib/active_support/core_ext/time/calculations.rb +36 -30
  78. data/lib/active_support/core_ext/time/compatibility.rb +16 -0
  79. data/lib/active_support/core_ext/time/conversions.rb +1 -3
  80. data/lib/active_support/core_ext/time/zones.rb +4 -4
  81. data/lib/active_support/core_ext/time.rb +0 -1
  82. data/lib/active_support/core_ext.rb +0 -1
  83. data/lib/active_support/current_attributes.rb +53 -46
  84. data/lib/active_support/deep_mergeable.rb +53 -0
  85. data/lib/active_support/delegation.rb +202 -0
  86. data/lib/active_support/dependencies/autoload.rb +9 -16
  87. data/lib/active_support/deprecation/behaviors.rb +65 -42
  88. data/lib/active_support/deprecation/constant_accessor.rb +47 -25
  89. data/lib/active_support/deprecation/deprecators.rb +104 -0
  90. data/lib/active_support/deprecation/disallowed.rb +3 -5
  91. data/lib/active_support/deprecation/method_wrappers.rb +6 -23
  92. data/lib/active_support/deprecation/proxy_wrappers.rb +34 -22
  93. data/lib/active_support/deprecation/reporting.rb +49 -27
  94. data/lib/active_support/deprecation.rb +39 -9
  95. data/lib/active_support/deprecator.rb +7 -0
  96. data/lib/active_support/descendants_tracker.rb +66 -172
  97. data/lib/active_support/duration/iso8601_parser.rb +2 -2
  98. data/lib/active_support/duration/iso8601_serializer.rb +1 -4
  99. data/lib/active_support/duration.rb +13 -7
  100. data/lib/active_support/encrypted_configuration.rb +30 -9
  101. data/lib/active_support/encrypted_file.rb +9 -4
  102. data/lib/active_support/environment_inquirer.rb +22 -2
  103. data/lib/active_support/error_reporter/test_helper.rb +15 -0
  104. data/lib/active_support/error_reporter.rb +160 -36
  105. data/lib/active_support/evented_file_update_checker.rb +0 -1
  106. data/lib/active_support/execution_wrapper.rb +4 -5
  107. data/lib/active_support/file_update_checker.rb +5 -3
  108. data/lib/active_support/fork_tracker.rb +4 -32
  109. data/lib/active_support/gem_version.rb +3 -3
  110. data/lib/active_support/gzip.rb +2 -0
  111. data/lib/active_support/hash_with_indifferent_access.rb +41 -25
  112. data/lib/active_support/html_safe_translation.rb +19 -6
  113. data/lib/active_support/i18n.rb +1 -1
  114. data/lib/active_support/i18n_railtie.rb +20 -13
  115. data/lib/active_support/inflector/inflections.rb +2 -0
  116. data/lib/active_support/inflector/methods.rb +23 -11
  117. data/lib/active_support/inflector/transliterate.rb +3 -1
  118. data/lib/active_support/isolated_execution_state.rb +26 -22
  119. data/lib/active_support/json/decoding.rb +2 -1
  120. data/lib/active_support/json/encoding.rb +25 -43
  121. data/lib/active_support/key_generator.rb +9 -1
  122. data/lib/active_support/lazy_load_hooks.rb +6 -4
  123. data/lib/active_support/locale/en.yml +2 -0
  124. data/lib/active_support/log_subscriber.rb +74 -34
  125. data/lib/active_support/logger.rb +22 -60
  126. data/lib/active_support/logger_thread_safe_level.rb +10 -32
  127. data/lib/active_support/message_encryptor.rb +197 -53
  128. data/lib/active_support/message_encryptors.rb +141 -0
  129. data/lib/active_support/message_pack/cache_serializer.rb +23 -0
  130. data/lib/active_support/message_pack/extensions.rb +305 -0
  131. data/lib/active_support/message_pack/serializer.rb +63 -0
  132. data/lib/active_support/message_pack.rb +50 -0
  133. data/lib/active_support/message_verifier.rb +220 -89
  134. data/lib/active_support/message_verifiers.rb +135 -0
  135. data/lib/active_support/messages/codec.rb +65 -0
  136. data/lib/active_support/messages/metadata.rb +111 -45
  137. data/lib/active_support/messages/rotation_coordinator.rb +93 -0
  138. data/lib/active_support/messages/rotator.rb +34 -32
  139. data/lib/active_support/messages/serializer_with_fallback.rb +158 -0
  140. data/lib/active_support/multibyte/chars.rb +4 -2
  141. data/lib/active_support/multibyte/unicode.rb +9 -37
  142. data/lib/active_support/notifications/fanout.rb +248 -87
  143. data/lib/active_support/notifications/instrumenter.rb +93 -25
  144. data/lib/active_support/notifications.rb +29 -28
  145. data/lib/active_support/number_helper/number_converter.rb +16 -7
  146. data/lib/active_support/number_helper/number_to_currency_converter.rb +6 -6
  147. data/lib/active_support/number_helper/number_to_human_size_converter.rb +3 -3
  148. data/lib/active_support/number_helper/number_to_phone_converter.rb +1 -0
  149. data/lib/active_support/number_helper.rb +379 -318
  150. data/lib/active_support/option_merger.rb +2 -2
  151. data/lib/active_support/ordered_hash.rb +3 -3
  152. data/lib/active_support/ordered_options.rb +67 -15
  153. data/lib/active_support/parameter_filter.rb +84 -69
  154. data/lib/active_support/proxy_object.rb +8 -3
  155. data/lib/active_support/railtie.rb +25 -20
  156. data/lib/active_support/reloader.rb +12 -4
  157. data/lib/active_support/rescuable.rb +2 -0
  158. data/lib/active_support/secure_compare_rotator.rb +16 -9
  159. data/lib/active_support/string_inquirer.rb +4 -2
  160. data/lib/active_support/subscriber.rb +10 -27
  161. data/lib/active_support/syntax_error_proxy.rb +60 -0
  162. data/lib/active_support/tagged_logging.rb +64 -25
  163. data/lib/active_support/test_case.rb +156 -7
  164. data/lib/active_support/testing/assertions.rb +28 -12
  165. data/lib/active_support/testing/autorun.rb +0 -2
  166. data/lib/active_support/testing/constant_stubbing.rb +54 -0
  167. data/lib/active_support/testing/deprecation.rb +20 -27
  168. data/lib/active_support/testing/error_reporter_assertions.rb +107 -0
  169. data/lib/active_support/testing/isolation.rb +21 -9
  170. data/lib/active_support/testing/method_call_assertions.rb +7 -8
  171. data/lib/active_support/testing/parallelization/server.rb +3 -0
  172. data/lib/active_support/testing/parallelize_executor.rb +8 -3
  173. data/lib/active_support/testing/setup_and_teardown.rb +2 -0
  174. data/lib/active_support/testing/stream.rb +1 -1
  175. data/lib/active_support/testing/strict_warnings.rb +43 -0
  176. data/lib/active_support/testing/tests_without_assertions.rb +19 -0
  177. data/lib/active_support/testing/time_helpers.rb +38 -16
  178. data/lib/active_support/time_with_zone.rb +12 -18
  179. data/lib/active_support/values/time_zone.rb +25 -14
  180. data/lib/active_support/version.rb +1 -1
  181. data/lib/active_support/xml_mini/jdom.rb +3 -10
  182. data/lib/active_support/xml_mini/nokogiri.rb +1 -1
  183. data/lib/active_support/xml_mini/nokogirisax.rb +1 -1
  184. data/lib/active_support/xml_mini/rexml.rb +1 -1
  185. data/lib/active_support/xml_mini.rb +12 -3
  186. data/lib/active_support.rb +15 -3
  187. metadata +145 -24
  188. data/lib/active_support/core_ext/array/deprecated_conversions.rb +0 -25
  189. data/lib/active_support/core_ext/date/deprecated_conversions.rb +0 -40
  190. data/lib/active_support/core_ext/date_time/deprecated_conversions.rb +0 -36
  191. data/lib/active_support/core_ext/numeric/deprecated_conversions.rb +0 -60
  192. data/lib/active_support/core_ext/range/deprecated_conversions.rb +0 -36
  193. data/lib/active_support/core_ext/range/include_time_with_zone.rb +0 -5
  194. data/lib/active_support/core_ext/range/overlaps.rb +0 -10
  195. data/lib/active_support/core_ext/time/deprecated_conversions.rb +0 -73
  196. data/lib/active_support/core_ext/uri.rb +0 -5
  197. data/lib/active_support/deprecation/instance_delegator.rb +0 -38
  198. data/lib/active_support/per_thread_registry.rb +0 -65
  199. data/lib/active_support/ruby_features.rb +0 -7
@@ -31,8 +31,8 @@ module ActiveSupport
31
31
  end
32
32
  end
33
33
 
34
- def respond_to_missing?(*arguments)
35
- @context.respond_to?(*arguments)
34
+ def respond_to_missing?(...)
35
+ @context.respond_to?(...)
36
36
  end
37
37
  end
38
38
  end
@@ -7,7 +7,7 @@ YAML.add_builtin_type("omap") do |type, val|
7
7
  end
8
8
 
9
9
  module ActiveSupport
10
- # DEPRECATED: <tt>ActiveSupport::OrderedHash</tt> implements a hash that preserves
10
+ # DEPRECATED: +ActiveSupport::OrderedHash+ implements a hash that preserves
11
11
  # insertion order.
12
12
  #
13
13
  # oh = ActiveSupport::OrderedHash.new
@@ -17,9 +17,9 @@ module ActiveSupport
17
17
  #
18
18
  # Also, maps the +omap+ feature for YAML files
19
19
  # (See https://yaml.org/type/omap.html) to support ordered items
20
- # when loading from yaml.
20
+ # when loading from YAML.
21
21
  #
22
- # <tt>ActiveSupport::OrderedHash</tt> is namespaced to prevent conflicts
22
+ # +ActiveSupport::OrderedHash+ is namespaced to prevent conflicts
23
23
  # with other implementations.
24
24
  class OrderedHash < ::Hash # :nodoc:
25
25
  def to_yaml_type
@@ -3,6 +3,8 @@
3
3
  require "active_support/core_ext/object/blank"
4
4
 
5
5
  module ActiveSupport
6
+ # = Ordered Options
7
+ #
6
8
  # +OrderedOptions+ inherits from +Hash+ and provides dynamic accessor methods.
7
9
  #
8
10
  # With a +Hash+, key-value pairs are typically managed like this:
@@ -40,18 +42,18 @@ module ActiveSupport
40
42
  super(key.to_sym)
41
43
  end
42
44
 
43
- def method_missing(name, *args)
44
- name_string = +name.to_s
45
- if name_string.chomp!("=")
46
- self[name_string] = args.first
47
- else
48
- bangs = name_string.chomp!("!")
45
+ def dig(key, *identifiers)
46
+ super(key.to_sym, *identifiers)
47
+ end
49
48
 
50
- if bangs
51
- self[name_string].presence || raise(KeyError.new(":#{name_string} is blank"))
52
- else
53
- self[name_string]
54
- end
49
+ def method_missing(method, *args)
50
+ if method.end_with?("=")
51
+ self[method.name.chomp("=")] = args.first
52
+ elsif method.end_with?("!")
53
+ name_string = method.name.chomp("!")
54
+ self[name_string].presence || raise(KeyError.new(":#{name_string} is blank"))
55
+ else
56
+ self[method.name]
55
57
  end
56
58
  end
57
59
 
@@ -68,6 +70,8 @@ module ActiveSupport
68
70
  end
69
71
  end
70
72
 
73
+ # = Inheritable Options
74
+ #
71
75
  # +InheritableOptions+ provides a constructor to build an OrderedOptions
72
76
  # hash inherited from another hash.
73
77
  #
@@ -76,20 +80,68 @@ module ActiveSupport
76
80
  # h = ActiveSupport::InheritableOptions.new({ girl: 'Mary', boy: 'John' })
77
81
  # h.girl # => 'Mary'
78
82
  # h.boy # => 'John'
83
+ #
84
+ # If the existing hash has string keys, call Hash#symbolize_keys on it.
85
+ #
86
+ # h = ActiveSupport::InheritableOptions.new({ 'girl' => 'Mary', 'boy' => 'John' }.symbolize_keys)
87
+ # h.girl # => 'Mary'
88
+ # h.boy # => 'John'
79
89
  class InheritableOptions < OrderedOptions
80
90
  def initialize(parent = nil)
81
- if parent.kind_of?(OrderedOptions)
91
+ @parent = parent
92
+ if @parent.kind_of?(OrderedOptions)
82
93
  # use the faster _get when dealing with OrderedOptions
83
- super() { |h, k| parent._get(k) }
84
- elsif parent
85
- super() { |h, k| parent[k] }
94
+ super() { |h, k| @parent._get(k) }
95
+ elsif @parent
96
+ super() { |h, k| @parent[k] }
86
97
  else
87
98
  super()
99
+ @parent = {}
88
100
  end
89
101
  end
90
102
 
103
+ def to_h
104
+ @parent.merge(self)
105
+ end
106
+
107
+ def ==(other)
108
+ to_h == other.to_h
109
+ end
110
+
111
+ def inspect
112
+ "#<#{self.class.name} #{to_h.inspect}>"
113
+ end
114
+
115
+ def to_s
116
+ to_h.to_s
117
+ end
118
+
119
+ def pretty_print(pp)
120
+ pp.pp_hash(to_h)
121
+ end
122
+
123
+ alias_method :own_key?, :key?
124
+ private :own_key?
125
+
126
+ def key?(key)
127
+ super || @parent.key?(key)
128
+ end
129
+
130
+ def overridden?(key)
131
+ !!(@parent && @parent.key?(key) && own_key?(key.to_sym))
132
+ end
133
+
91
134
  def inheritable_copy
92
135
  self.class.new(self)
93
136
  end
137
+
138
+ def to_a
139
+ entries
140
+ end
141
+
142
+ def each(&block)
143
+ to_h.each(&block)
144
+ self
145
+ end
94
146
  end
95
147
  end
@@ -1,8 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "active_support/core_ext/object/duplicable"
4
+ require "active_support/core_ext/array/extract"
4
5
 
5
6
  module ActiveSupport
7
+ # = Active Support Parameter Filter
8
+ #
6
9
  # +ParameterFilter+ replaces values in a <tt>Hash</tt>-like object if their
7
10
  # keys match one of the specified filters.
8
11
  #
@@ -36,6 +39,34 @@ module ActiveSupport
36
39
  class ParameterFilter
37
40
  FILTERED = "[FILTERED]" # :nodoc:
38
41
 
42
+ # Precompiles an array of filters that otherwise would be passed directly to
43
+ # #initialize. Depending on the quantity and types of filters,
44
+ # precompilation can improve filtering performance, especially in the case
45
+ # where the ParameterFilter instance itself cannot be retained (but the
46
+ # precompiled filters can be retained).
47
+ #
48
+ # filters = [/foo/, :bar, "nested.baz", /nested\.qux/]
49
+ #
50
+ # precompiled = ActiveSupport::ParameterFilter.precompile_filters(filters)
51
+ # # => [/(?-mix:foo)|(?i:bar)/, /(?i:nested\.baz)|(?-mix:nested\.qux)/]
52
+ #
53
+ # ActiveSupport::ParameterFilter.new(precompiled)
54
+ #
55
+ def self.precompile_filters(filters)
56
+ filters, patterns = filters.partition { |filter| filter.is_a?(Proc) }
57
+
58
+ patterns.map! do |pattern|
59
+ pattern.is_a?(Regexp) ? pattern : "(?i:#{Regexp.escape pattern.to_s})"
60
+ end
61
+
62
+ deep_patterns = patterns.extract! { |pattern| pattern.to_s.include?("\\.") }
63
+
64
+ filters << Regexp.new(patterns.join("|")) if patterns.any?
65
+ filters << Regexp.new(deep_patterns.join("|")) if deep_patterns.any?
66
+
67
+ filters
68
+ end
69
+
39
70
  # Create instance with given filters. Supported type of filters are +String+, +Regexp+, and +Proc+.
40
71
  # Other types of filters are treated as +String+ using +to_s+.
41
72
  # For +Proc+ filters, key, value, and optional original hash is passed to block arguments.
@@ -44,99 +75,83 @@ module ActiveSupport
44
75
  #
45
76
  # * <tt>:mask</tt> - A replaced object when filtered. Defaults to <tt>"[FILTERED]"</tt>.
46
77
  def initialize(filters = [], mask: FILTERED)
47
- @filters = filters
48
78
  @mask = mask
79
+ compile_filters!(filters)
49
80
  end
50
81
 
51
82
  # Mask value of +params+ if key matches one of filters.
52
83
  def filter(params)
53
- compiled_filter.call(params)
84
+ @no_filters ? params.dup : call(params)
54
85
  end
55
86
 
56
87
  # Returns filtered value for given key. For +Proc+ filters, third block argument is not populated.
57
88
  def filter_param(key, value)
58
- @filters.empty? ? value : compiled_filter.value_for_key(key, value)
89
+ @no_filters ? value : value_for_key(key, value)
59
90
  end
60
91
 
61
92
  private
62
- def compiled_filter
63
- @compiled_filter ||= CompiledFilter.compile(@filters, mask: @mask)
64
- end
65
-
66
- class CompiledFilter # :nodoc:
67
- def self.compile(filters, mask:)
68
- return lambda { |params| params.dup } if filters.empty?
69
-
70
- strings, regexps, blocks, deep_regexps, deep_strings = [], [], [], nil, nil
71
-
72
- filters.each do |item|
73
- case item
74
- when Proc
75
- blocks << item
76
- when Regexp
77
- if item.to_s.include?("\\.")
78
- (deep_regexps ||= []) << item
79
- else
80
- regexps << item
81
- end
93
+ def compile_filters!(filters)
94
+ @no_filters = filters.empty?
95
+ return if @no_filters
96
+
97
+ @regexps, strings = [], []
98
+ @deep_regexps, deep_strings = nil, nil
99
+ @blocks = nil
100
+
101
+ filters.each do |item|
102
+ case item
103
+ when Proc
104
+ (@blocks ||= []) << item
105
+ when Regexp
106
+ if item.to_s.include?("\\.")
107
+ (@deep_regexps ||= []) << item
108
+ else
109
+ @regexps << item
110
+ end
111
+ else
112
+ s = Regexp.escape(item.to_s)
113
+ if s.include?("\\.")
114
+ (deep_strings ||= []) << s
82
115
  else
83
- s = Regexp.escape(item.to_s)
84
- if s.include?("\\.")
85
- (deep_strings ||= []) << s
86
- else
87
- strings << s
88
- end
116
+ strings << s
89
117
  end
90
118
  end
91
-
92
- regexps << Regexp.new(strings.join("|"), true) unless strings.empty?
93
- (deep_regexps ||= []) << Regexp.new(deep_strings.join("|"), true) if deep_strings&.any?
94
-
95
- new regexps, deep_regexps, blocks, mask: mask
96
119
  end
97
120
 
98
- attr_reader :regexps, :deep_regexps, :blocks
121
+ @regexps << Regexp.new(strings.join("|"), true) unless strings.empty?
122
+ (@deep_regexps ||= []) << Regexp.new(deep_strings.join("|"), true) if deep_strings
123
+ end
124
+
125
+ def call(params, full_parent_key = nil, original_params = params)
126
+ filtered_params = params.class.new
99
127
 
100
- def initialize(regexps, deep_regexps, blocks, mask:)
101
- @regexps = regexps
102
- @deep_regexps = deep_regexps&.any? ? deep_regexps : nil
103
- @blocks = blocks
104
- @mask = mask
128
+ params.each do |key, value|
129
+ filtered_params[key] = value_for_key(key, value, full_parent_key, original_params)
105
130
  end
106
131
 
107
- def call(params, parents = [], original_params = params)
108
- filtered_params = params.class.new
109
-
110
- params.each do |key, value|
111
- filtered_params[key] = value_for_key(key, value, parents, original_params)
112
- end
132
+ filtered_params
133
+ end
113
134
 
114
- filtered_params
135
+ def value_for_key(key, value, full_parent_key = nil, original_params = nil)
136
+ if @deep_regexps
137
+ full_key = full_parent_key ? "#{full_parent_key}.#{key}" : key.to_s
115
138
  end
116
139
 
117
- def value_for_key(key, value, parents = [], original_params = nil)
118
- parents.push(key) if deep_regexps
119
- if regexps.any? { |r| r.match?(key.to_s) }
120
- value = @mask
121
- elsif deep_regexps && (joined = parents.join(".")) && deep_regexps.any? { |r| r.match?(joined) }
122
- value = @mask
123
- elsif value.is_a?(Hash)
124
- value = call(value, parents, original_params)
125
- elsif value.is_a?(Array)
126
- # If we don't pop the current parent it will be duplicated as we
127
- # process each array value.
128
- parents.pop if deep_regexps
129
- value = value.map { |v| value_for_key(key, v, parents, original_params) }
130
- # Restore the parent stack after processing the array.
131
- parents.push(key) if deep_regexps
132
- elsif blocks.any?
133
- key = key.dup if key.duplicable?
134
- value = value.dup if value.duplicable?
135
- blocks.each { |b| b.arity == 2 ? b.call(key, value) : b.call(key, value, original_params) }
136
- end
137
- parents.pop if deep_regexps
138
- value
140
+ if @regexps.any? { |r| r.match?(key.to_s) }
141
+ value = @mask
142
+ elsif @deep_regexps&.any? { |r| r.match?(full_key) }
143
+ value = @mask
144
+ elsif value.is_a?(Hash)
145
+ value = call(value, full_key, original_params)
146
+ elsif value.is_a?(Array)
147
+ value = value.map { |v| value_for_key(key, v, full_parent_key, original_params) }
148
+ elsif @blocks
149
+ key = key.dup if key.duplicable?
150
+ value = value.dup if value.duplicable?
151
+ @blocks.each { |b| b.arity == 2 ? b.call(key, value) : b.call(key, value, original_params) }
139
152
  end
153
+
154
+ value
140
155
  end
141
156
  end
142
157
  end
@@ -1,9 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ActiveSupport
4
- # A class with no predefined methods that behaves similarly to Builder's
5
- # BlankSlate. Used for proxy classes.
6
- class ProxyObject < ::BasicObject
4
+ class ProxyObject < ::BasicObject # :nodoc:
7
5
  undef_method :==
8
6
  undef_method :equal?
9
7
 
@@ -11,5 +9,12 @@ module ActiveSupport
11
9
  def raise(*args)
12
10
  ::Object.send(:raise, *args)
13
11
  end
12
+
13
+ def self.inherited(_subclass)
14
+ ::ActiveSupport.deprecator.warn(<<~MSG)
15
+ ActiveSupport::ProxyObject is deprecated and will be removed in Rails 8.0.
16
+ Use Ruby's built-in BasicObject instead.
17
+ MSG
18
+ end
14
19
  end
15
20
  end
@@ -6,10 +6,13 @@ require "active_support/i18n_railtie"
6
6
  module ActiveSupport
7
7
  class Railtie < Rails::Railtie # :nodoc:
8
8
  config.active_support = ActiveSupport::OrderedOptions.new
9
- config.active_support.disable_to_s_conversion = false
10
9
 
11
10
  config.eager_load_namespaces << ActiveSupport
12
11
 
12
+ initializer "active_support.deprecator", before: :load_environment_config do |app|
13
+ app.deprecators[:active_support] = ActiveSupport.deprecator
14
+ end
15
+
13
16
  initializer "active_support.isolation_level" do |app|
14
17
  config.after_initialize do
15
18
  if level = app.config.active_support.delete(:isolation_level)
@@ -18,11 +21,10 @@ module ActiveSupport
18
21
  end
19
22
  end
20
23
 
21
- initializer "active_support.remove_deprecated_time_with_zone_name" do |app|
24
+ initializer "active_support.raise_on_invalid_cache_expiration_time" do |app|
22
25
  config.after_initialize do
23
- if app.config.active_support.remove_deprecated_time_with_zone_name
24
- require "active_support/time_with_zone"
25
- TimeWithZone.singleton_class.remove_method(:name)
26
+ if app.config.active_support.raise_on_invalid_cache_expiration_time
27
+ ActiveSupport::Cache::Store.raise_on_invalid_cache_expiration_time = true
26
28
  end
27
29
  end
28
30
  end
@@ -63,20 +65,20 @@ module ActiveSupport
63
65
 
64
66
  initializer "active_support.deprecation_behavior" do |app|
65
67
  if app.config.active_support.report_deprecations == false
66
- ActiveSupport::Deprecation.silenced = true
67
- ActiveSupport::Deprecation.behavior = :silence
68
- ActiveSupport::Deprecation.disallowed_behavior = :silence
68
+ app.deprecators.silenced = true
69
+ app.deprecators.behavior = :silence
70
+ app.deprecators.disallowed_behavior = :silence
69
71
  else
70
72
  if deprecation = app.config.active_support.deprecation
71
- ActiveSupport::Deprecation.behavior = deprecation
73
+ app.deprecators.behavior = deprecation
72
74
  end
73
75
 
74
76
  if disallowed_deprecation = app.config.active_support.disallowed_deprecation
75
- ActiveSupport::Deprecation.disallowed_behavior = disallowed_deprecation
77
+ app.deprecators.disallowed_behavior = disallowed_deprecation
76
78
  end
77
79
 
78
80
  if disallowed_warnings = app.config.active_support.disallowed_deprecation_warnings
79
- ActiveSupport::Deprecation.disallowed_warnings = disallowed_warnings
81
+ app.deprecators.disallowed_warnings = disallowed_warnings
80
82
  end
81
83
  end
82
84
  end
@@ -87,10 +89,11 @@ module ActiveSupport
87
89
  begin
88
90
  TZInfo::DataSource.get
89
91
  rescue TZInfo::DataSourceNotFound => e
90
- raise e.exception "tzinfo-data is not present. Please add gem 'tzinfo-data' to your Gemfile and run bundle install"
92
+ raise e.exception('tzinfo-data is not present. Please add gem "tzinfo-data" to your Gemfile and run bundle install')
91
93
  end
92
94
  require "active_support/core_ext/time/zones"
93
95
  Time.zone_default = Time.find_zone!(app.config.time_zone)
96
+ config.eager_load_namespaces << TZInfo
94
97
  end
95
98
 
96
99
  # Sets the default week start
@@ -113,10 +116,6 @@ module ActiveSupport
113
116
  end
114
117
  end
115
118
 
116
- initializer "active_support.set_error_reporter" do |app|
117
- ActiveSupport.error_reporter = app.executor.error_reporter
118
- end
119
-
120
119
  initializer "active_support.set_configs" do |app|
121
120
  app.config.active_support.each do |k, v|
122
121
  k = "#{k}="
@@ -140,13 +139,19 @@ module ActiveSupport
140
139
  end
141
140
  end
142
141
 
143
- initializer "active_support.set_rfc4122_namespaced_uuids" do |app|
142
+ initializer "active_support.set_default_message_serializer" do |app|
144
143
  config.after_initialize do
145
- if app.config.active_support.use_rfc4122_namespaced_uuids
146
- require "active_support/core_ext/digest"
147
- ::Digest::UUID.use_rfc4122_namespaced_uuids = app.config.active_support.use_rfc4122_namespaced_uuids
144
+ if message_serializer = app.config.active_support.message_serializer
145
+ ActiveSupport::Messages::Codec.default_serializer = message_serializer
148
146
  end
149
147
  end
150
148
  end
149
+
150
+ initializer "active_support.set_use_message_serializer_for_metadata" do |app|
151
+ config.after_initialize do
152
+ ActiveSupport::Messages::Metadata.use_message_serializer_for_metadata =
153
+ app.config.active_support.use_message_serializer_for_metadata
154
+ end
155
+ end
151
156
  end
152
157
  end
@@ -4,7 +4,8 @@ require "active_support/execution_wrapper"
4
4
  require "active_support/executor"
5
5
 
6
6
  module ActiveSupport
7
- #--
7
+ # = Active Support \Reloader
8
+ #
8
9
  # This class defines several callbacks:
9
10
  #
10
11
  # to_prepare -- Run once at application startup, and also from
@@ -67,9 +68,16 @@ module ActiveSupport
67
68
  end
68
69
 
69
70
  # Run the supplied block as a work unit, reloading code as needed
70
- def self.wrap
71
- executor.wrap do
72
- super
71
+ def self.wrap(**kwargs)
72
+ return yield if active?
73
+
74
+ executor.wrap(**kwargs) do
75
+ instance = run!
76
+ begin
77
+ yield
78
+ ensure
79
+ instance.complete!
80
+ end
73
81
  end
74
82
  end
75
83
 
@@ -5,6 +5,8 @@ require "active_support/core_ext/class/attribute"
5
5
  require "active_support/core_ext/string/inflections"
6
6
 
7
7
  module ActiveSupport
8
+ # = Active Support \Rescuable
9
+ #
8
10
  # Rescuable module adds support for easier exception handling.
9
11
  module Rescuable
10
12
  extend Concern
@@ -4,6 +4,8 @@ require "active_support/security_utils"
4
4
  require "active_support/messages/rotator"
5
5
 
6
6
  module ActiveSupport
7
+ # = Secure Compare Rotator
8
+ #
7
9
  # The ActiveSupport::SecureCompareRotator is a wrapper around ActiveSupport::SecurityUtils.secure_compare
8
10
  # and allows you to rotate a previously defined value to a new one.
9
11
  #
@@ -29,23 +31,28 @@ module ActiveSupport
29
31
  # end
30
32
  class SecureCompareRotator
31
33
  include SecurityUtils
32
- prepend Messages::Rotator
33
34
 
34
35
  InvalidMatch = Class.new(StandardError)
35
36
 
36
- def initialize(value, **_options)
37
+ def initialize(value, on_rotation: nil)
37
38
  @value = value
39
+ @rotate_values = []
40
+ @on_rotation = on_rotation
38
41
  end
39
42
 
40
- def secure_compare!(other_value, on_rotation: @on_rotation)
41
- secure_compare(@value, other_value) ||
42
- run_rotations(on_rotation) { |wrapper| wrapper.secure_compare!(other_value) } ||
43
- raise(InvalidMatch)
43
+ def rotate(previous_value)
44
+ @rotate_values << previous_value
44
45
  end
45
46
 
46
- private
47
- def build_rotation(previous_value, _options)
48
- self.class.new(previous_value)
47
+ def secure_compare!(other_value, on_rotation: @on_rotation)
48
+ if secure_compare(@value, other_value)
49
+ true
50
+ elsif @rotate_values.any? { |value| secure_compare(value, other_value) }
51
+ on_rotation&.call
52
+ true
53
+ else
54
+ raise InvalidMatch
49
55
  end
56
+ end
50
57
  end
51
58
  end
@@ -1,6 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ActiveSupport
4
+ # = \String Inquirer
5
+ #
4
6
  # Wrapping a string in this class gives you a prettier way to test
5
7
  # for equality. The value returned by <tt>Rails.env</tt> is wrapped
6
8
  # in a StringInquirer object, so instead of calling this:
@@ -11,7 +13,7 @@ module ActiveSupport
11
13
  #
12
14
  # Rails.env.production?
13
15
  #
14
- # == Instantiating a new StringInquirer
16
+ # == Instantiating a new \StringInquirer
15
17
  #
16
18
  # vehicle = ActiveSupport::StringInquirer.new('car')
17
19
  # vehicle.car? # => true
@@ -22,7 +24,7 @@ module ActiveSupport
22
24
  method_name.end_with?("?") || super
23
25
  end
24
26
 
25
- def method_missing(method_name, *arguments)
27
+ def method_missing(method_name, ...)
26
28
  if method_name.end_with?("?")
27
29
  self == method_name[0..-2]
28
30
  else
@@ -3,7 +3,9 @@
3
3
  require "active_support/notifications"
4
4
 
5
5
  module ActiveSupport
6
- # ActiveSupport::Subscriber is an object set to consume
6
+ # = Active Support \Subscriber
7
+ #
8
+ # +ActiveSupport::Subscriber+ is an object set to consume
7
9
  # ActiveSupport::Notifications. The subscriber dispatches notifications to
8
10
  # a registered object based on its given namespace.
9
11
  #
@@ -20,9 +22,9 @@ module ActiveSupport
20
22
  # end
21
23
  # end
22
24
  #
23
- # After configured, whenever a "sql.active_record" notification is published,
24
- # it will properly dispatch the event (ActiveSupport::Notifications::Event) to
25
- # the +sql+ method.
25
+ # After configured, whenever a <tt>"sql.active_record"</tt> notification is
26
+ # published, it will properly dispatch the event
27
+ # (ActiveSupport::Notifications::Event) to the +sql+ method.
26
28
  #
27
29
  # We can detach a subscriber as well:
28
30
  #
@@ -65,6 +67,7 @@ module ActiveSupport
65
67
 
66
68
  # Adds event subscribers for all new methods added to the class.
67
69
  def method_added(event)
70
+ super
68
71
  # Only public methods are added as subscribers, and only if a notifier
69
72
  # has been set up. This means that subscribers will only be set up for
70
73
  # classes that call #attach_to.
@@ -126,38 +129,18 @@ module ActiveSupport
126
129
  attr_reader :patterns # :nodoc:
127
130
 
128
131
  def initialize
129
- @queue_key = [self.class.name, object_id].join "-"
130
132
  @patterns = {}
131
133
  super
132
134
  end
133
135
 
134
- def start(name, id, payload)
135
- event = ActiveSupport::Notifications::Event.new(name, nil, nil, id, payload)
136
- event.start!
137
- parent = event_stack.last
138
- parent << event if parent
139
-
140
- event_stack.push event
141
- end
142
-
143
- def finish(name, id, payload)
144
- event = event_stack.pop
145
- event.finish!
146
- event.payload.merge!(payload)
147
-
148
- method = name.split(".").first
136
+ def call(event)
137
+ method = event.name[0, event.name.index(".")]
149
138
  send(method, event)
150
139
  end
151
140
 
152
141
  def publish_event(event) # :nodoc:
153
- method = event.name.split(".").first
142
+ method = event.name[0, event.name.index(".")]
154
143
  send(method, event)
155
144
  end
156
-
157
- private
158
- def event_stack
159
- registry = ActiveSupport::IsolatedExecutionState[:active_support_subscriber_queue_registry] ||= {}
160
- registry[@queue_key] ||= []
161
- end
162
145
  end
163
146
  end