activesupport 6.1.6.1 → 7.0.3.1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of activesupport might be problematic. Click here for more details.

Files changed (179) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +231 -515
  3. data/lib/active_support/actionable_error.rb +1 -1
  4. data/lib/active_support/array_inquirer.rb +0 -2
  5. data/lib/active_support/backtrace_cleaner.rb +2 -2
  6. data/lib/active_support/benchmarkable.rb +2 -2
  7. data/lib/active_support/cache/file_store.rb +15 -9
  8. data/lib/active_support/cache/mem_cache_store.rb +132 -37
  9. data/lib/active_support/cache/memory_store.rb +24 -16
  10. data/lib/active_support/cache/null_store.rb +10 -2
  11. data/lib/active_support/cache/redis_cache_store.rb +47 -72
  12. data/lib/active_support/cache/strategy/local_cache.rb +38 -61
  13. data/lib/active_support/cache.rb +193 -46
  14. data/lib/active_support/callbacks.rb +184 -85
  15. data/lib/active_support/code_generator.rb +65 -0
  16. data/lib/active_support/concern.rb +5 -5
  17. data/lib/active_support/concurrency/load_interlock_aware_monitor.rb +2 -4
  18. data/lib/active_support/concurrency/share_lock.rb +2 -2
  19. data/lib/active_support/configurable.rb +8 -5
  20. data/lib/active_support/configuration_file.rb +1 -1
  21. data/lib/active_support/core_ext/array/access.rb +1 -5
  22. data/lib/active_support/core_ext/array/conversions.rb +13 -12
  23. data/lib/active_support/core_ext/array/deprecated_conversions.rb +25 -0
  24. data/lib/active_support/core_ext/array/grouping.rb +6 -6
  25. data/lib/active_support/core_ext/array/inquiry.rb +2 -2
  26. data/lib/active_support/core_ext/array.rb +1 -0
  27. data/lib/active_support/core_ext/big_decimal/conversions.rb +1 -1
  28. data/lib/active_support/core_ext/class/subclasses.rb +25 -17
  29. data/lib/active_support/core_ext/date/blank.rb +1 -1
  30. data/lib/active_support/core_ext/date/calculations.rb +9 -9
  31. data/lib/active_support/core_ext/date/conversions.rb +14 -14
  32. data/lib/active_support/core_ext/date/deprecated_conversions.rb +26 -0
  33. data/lib/active_support/core_ext/date.rb +1 -0
  34. data/lib/active_support/core_ext/date_and_time/calculations.rb +4 -4
  35. data/lib/active_support/core_ext/date_and_time/compatibility.rb +1 -1
  36. data/lib/active_support/core_ext/date_time/blank.rb +1 -1
  37. data/lib/active_support/core_ext/date_time/conversions.rb +13 -13
  38. data/lib/active_support/core_ext/date_time/deprecated_conversions.rb +22 -0
  39. data/lib/active_support/core_ext/date_time.rb +1 -0
  40. data/lib/active_support/core_ext/digest/uuid.rb +39 -14
  41. data/lib/active_support/core_ext/enumerable.rb +101 -32
  42. data/lib/active_support/core_ext/file/atomic.rb +3 -1
  43. data/lib/active_support/core_ext/hash/conversions.rb +0 -1
  44. data/lib/active_support/core_ext/hash/indifferent_access.rb +3 -3
  45. data/lib/active_support/core_ext/hash/keys.rb +1 -1
  46. data/lib/active_support/core_ext/kernel/reporting.rb +4 -4
  47. data/lib/active_support/core_ext/kernel/singleton_class.rb +1 -1
  48. data/lib/active_support/core_ext/module/attribute_accessors.rb +2 -0
  49. data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +19 -10
  50. data/lib/active_support/core_ext/module/delegation.rb +2 -8
  51. data/lib/active_support/core_ext/name_error.rb +2 -8
  52. data/lib/active_support/core_ext/numeric/conversions.rb +80 -77
  53. data/lib/active_support/core_ext/numeric/deprecated_conversions.rb +60 -0
  54. data/lib/active_support/core_ext/numeric.rb +1 -0
  55. data/lib/active_support/core_ext/object/acts_like.rb +29 -5
  56. data/lib/active_support/core_ext/object/blank.rb +2 -2
  57. data/lib/active_support/core_ext/object/deep_dup.rb +1 -1
  58. data/lib/active_support/core_ext/object/duplicable.rb +11 -0
  59. data/lib/active_support/core_ext/object/json.rb +30 -25
  60. data/lib/active_support/core_ext/object/to_query.rb +2 -2
  61. data/lib/active_support/core_ext/object/try.rb +20 -20
  62. data/lib/active_support/core_ext/object/with_options.rb +20 -1
  63. data/lib/active_support/core_ext/pathname/existence.rb +21 -0
  64. data/lib/active_support/core_ext/pathname.rb +3 -0
  65. data/lib/active_support/core_ext/range/compare_range.rb +0 -25
  66. data/lib/active_support/core_ext/range/conversions.rb +8 -8
  67. data/lib/active_support/core_ext/range/deprecated_conversions.rb +26 -0
  68. data/lib/active_support/core_ext/range/each.rb +1 -1
  69. data/lib/active_support/core_ext/range/include_time_with_zone.rb +4 -25
  70. data/lib/active_support/core_ext/range/overlaps.rb +1 -1
  71. data/lib/active_support/core_ext/range.rb +1 -1
  72. data/lib/active_support/core_ext/securerandom.rb +1 -1
  73. data/lib/active_support/core_ext/string/conversions.rb +2 -2
  74. data/lib/active_support/core_ext/string/filters.rb +1 -1
  75. data/lib/active_support/core_ext/string/inflections.rb +1 -1
  76. data/lib/active_support/core_ext/string/inquiry.rb +1 -1
  77. data/lib/active_support/core_ext/string/output_safety.rb +62 -38
  78. data/lib/active_support/core_ext/symbol/starts_ends_with.rb +0 -8
  79. data/lib/active_support/core_ext/time/calculations.rb +7 -8
  80. data/lib/active_support/core_ext/time/conversions.rb +13 -12
  81. data/lib/active_support/core_ext/time/deprecated_conversions.rb +22 -0
  82. data/lib/active_support/core_ext/time/zones.rb +7 -22
  83. data/lib/active_support/core_ext/time.rb +1 -0
  84. data/lib/active_support/core_ext/uri.rb +3 -27
  85. data/lib/active_support/core_ext.rb +1 -0
  86. data/lib/active_support/current_attributes.rb +31 -14
  87. data/lib/active_support/dependencies/interlock.rb +10 -18
  88. data/lib/active_support/dependencies/require_dependency.rb +28 -0
  89. data/lib/active_support/dependencies.rb +58 -788
  90. data/lib/active_support/deprecation/behaviors.rb +5 -2
  91. data/lib/active_support/deprecation/method_wrappers.rb +3 -3
  92. data/lib/active_support/deprecation/proxy_wrappers.rb +2 -2
  93. data/lib/active_support/deprecation.rb +2 -2
  94. data/lib/active_support/descendants_tracker.rb +174 -68
  95. data/lib/active_support/digest.rb +4 -4
  96. data/lib/active_support/duration/iso8601_parser.rb +3 -3
  97. data/lib/active_support/duration/iso8601_serializer.rb +9 -1
  98. data/lib/active_support/duration.rb +77 -48
  99. data/lib/active_support/encrypted_configuration.rb +13 -2
  100. data/lib/active_support/encrypted_file.rb +1 -1
  101. data/lib/active_support/environment_inquirer.rb +1 -1
  102. data/lib/active_support/error_reporter.rb +117 -0
  103. data/lib/active_support/evented_file_update_checker.rb +3 -5
  104. data/lib/active_support/execution_context/test_helper.rb +13 -0
  105. data/lib/active_support/execution_context.rb +53 -0
  106. data/lib/active_support/execution_wrapper.rb +30 -11
  107. data/lib/active_support/executor/test_helper.rb +7 -0
  108. data/lib/active_support/fork_tracker.rb +19 -12
  109. data/lib/active_support/gem_version.rb +4 -4
  110. data/lib/active_support/hash_with_indifferent_access.rb +3 -1
  111. data/lib/active_support/html_safe_translation.rb +43 -0
  112. data/lib/active_support/i18n.rb +1 -0
  113. data/lib/active_support/i18n_railtie.rb +1 -1
  114. data/lib/active_support/inflector/inflections.rb +23 -7
  115. data/lib/active_support/inflector/methods.rb +24 -48
  116. data/lib/active_support/inflector/transliterate.rb +1 -1
  117. data/lib/active_support/isolated_execution_state.rb +72 -0
  118. data/lib/active_support/json/encoding.rb +3 -3
  119. data/lib/active_support/key_generator.rb +22 -5
  120. data/lib/active_support/lazy_load_hooks.rb +14 -3
  121. data/lib/active_support/locale/en.yml +1 -1
  122. data/lib/active_support/log_subscriber/test_helper.rb +2 -2
  123. data/lib/active_support/log_subscriber.rb +15 -5
  124. data/lib/active_support/logger.rb +4 -5
  125. data/lib/active_support/logger_thread_safe_level.rb +4 -13
  126. data/lib/active_support/message_encryptor.rb +12 -6
  127. data/lib/active_support/message_verifier.rb +46 -14
  128. data/lib/active_support/messages/metadata.rb +2 -2
  129. data/lib/active_support/multibyte/chars.rb +10 -11
  130. data/lib/active_support/multibyte/unicode.rb +0 -12
  131. data/lib/active_support/multibyte.rb +1 -1
  132. data/lib/active_support/notifications/fanout.rb +91 -65
  133. data/lib/active_support/notifications/instrumenter.rb +32 -15
  134. data/lib/active_support/notifications.rb +17 -23
  135. data/lib/active_support/number_helper/number_converter.rb +1 -3
  136. data/lib/active_support/number_helper/number_to_currency_converter.rb +11 -6
  137. data/lib/active_support/number_helper/number_to_delimited_converter.rb +1 -1
  138. data/lib/active_support/number_helper/number_to_human_size_converter.rb +1 -1
  139. data/lib/active_support/number_helper/number_to_phone_converter.rb +1 -1
  140. data/lib/active_support/number_helper/rounding_helper.rb +1 -5
  141. data/lib/active_support/number_helper.rb +0 -2
  142. data/lib/active_support/option_merger.rb +8 -16
  143. data/lib/active_support/ordered_hash.rb +1 -1
  144. data/lib/active_support/ordered_options.rb +1 -1
  145. data/lib/active_support/parameter_filter.rb +5 -0
  146. data/lib/active_support/per_thread_registry.rb +5 -1
  147. data/lib/active_support/railtie.rb +69 -19
  148. data/lib/active_support/rescuable.rb +4 -4
  149. data/lib/active_support/ruby_features.rb +7 -0
  150. data/lib/active_support/secure_compare_rotator.rb +2 -2
  151. data/lib/active_support/string_inquirer.rb +0 -2
  152. data/lib/active_support/subscriber.rb +7 -18
  153. data/lib/active_support/tagged_logging.rb +16 -1
  154. data/lib/active_support/test_case.rb +9 -21
  155. data/lib/active_support/testing/assertions.rb +35 -5
  156. data/lib/active_support/testing/deprecation.rb +52 -1
  157. data/lib/active_support/testing/isolation.rb +2 -2
  158. data/lib/active_support/testing/method_call_assertions.rb +5 -5
  159. data/lib/active_support/testing/parallelization/server.rb +4 -0
  160. data/lib/active_support/testing/parallelization/worker.rb +3 -0
  161. data/lib/active_support/testing/parallelization.rb +4 -0
  162. data/lib/active_support/testing/parallelize_executor.rb +76 -0
  163. data/lib/active_support/testing/stream.rb +3 -5
  164. data/lib/active_support/testing/tagged_logging.rb +1 -1
  165. data/lib/active_support/testing/time_helpers.rb +13 -2
  166. data/lib/active_support/time_with_zone.rb +58 -17
  167. data/lib/active_support/values/time_zone.rb +33 -14
  168. data/lib/active_support/version.rb +1 -1
  169. data/lib/active_support/xml_mini/jdom.rb +1 -1
  170. data/lib/active_support/xml_mini/libxml.rb +5 -5
  171. data/lib/active_support/xml_mini/libxmlsax.rb +1 -1
  172. data/lib/active_support/xml_mini/nokogiri.rb +4 -4
  173. data/lib/active_support/xml_mini/nokogirisax.rb +1 -1
  174. data/lib/active_support/xml_mini/rexml.rb +1 -1
  175. data/lib/active_support/xml_mini.rb +5 -4
  176. data/lib/active_support.rb +16 -0
  177. metadata +23 -21
  178. data/lib/active_support/core_ext/marshal.rb +0 -26
  179. data/lib/active_support/dependencies/zeitwerk_integration.rb +0 -120
@@ -31,6 +31,10 @@ module ActiveSupport
31
31
  end
32
32
  end
33
33
 
34
+ def new_event(name, payload = {}) # :nodoc:
35
+ Event.new(name, nil, nil, @id, payload)
36
+ end
37
+
34
38
  # Send a start notification with +name+ and +payload+.
35
39
  def start(name, payload)
36
40
  @notifier.start name, @id, payload
@@ -58,16 +62,29 @@ module ActiveSupport
58
62
  def initialize(name, start, ending, transaction_id, payload)
59
63
  @name = name
60
64
  @payload = payload.dup
61
- @time = start
65
+ @time = start ? start.to_f * 1_000.0 : start
62
66
  @transaction_id = transaction_id
63
- @end = ending
67
+ @end = ending ? ending.to_f * 1_000.0 : ending
64
68
  @children = []
65
- @cpu_time_start = 0
66
- @cpu_time_finish = 0
69
+ @cpu_time_start = 0.0
70
+ @cpu_time_finish = 0.0
67
71
  @allocation_count_start = 0
68
72
  @allocation_count_finish = 0
69
73
  end
70
74
 
75
+ def record
76
+ start!
77
+ begin
78
+ yield payload if block_given?
79
+ rescue Exception => e
80
+ payload[:exception] = [e.class.name, e.message]
81
+ payload[:exception_object] = e
82
+ raise e
83
+ ensure
84
+ finish!
85
+ end
86
+ end
87
+
71
88
  # Record information at the time this event starts
72
89
  def start!
73
90
  @time = now
@@ -85,7 +102,7 @@ module ActiveSupport
85
102
  # Returns the CPU time (in milliseconds) passed since the call to
86
103
  # +start!+ and the call to +finish!+
87
104
  def cpu_time
88
- (@cpu_time_finish - @cpu_time_start) * 1000
105
+ @cpu_time_finish - @cpu_time_start
89
106
  end
90
107
 
91
108
  # Returns the idle time time (in milliseconds) passed since the call to
@@ -113,7 +130,7 @@ module ActiveSupport
113
130
  #
114
131
  # @event.duration # => 1000.138
115
132
  def duration
116
- 1000.0 * (self.end - time)
133
+ self.end - time
117
134
  end
118
135
 
119
136
  def <<(event)
@@ -126,28 +143,28 @@ module ActiveSupport
126
143
 
127
144
  private
128
145
  def now
129
- Concurrent.monotonic_time
146
+ Process.clock_gettime(Process::CLOCK_MONOTONIC, :float_millisecond)
130
147
  end
131
148
 
132
149
  begin
133
- Process.clock_gettime(Process::CLOCK_THREAD_CPUTIME_ID)
150
+ Process.clock_gettime(Process::CLOCK_THREAD_CPUTIME_ID, :float_millisecond)
134
151
 
135
152
  def now_cpu
136
- Process.clock_gettime(Process::CLOCK_THREAD_CPUTIME_ID)
153
+ Process.clock_gettime(Process::CLOCK_THREAD_CPUTIME_ID, :float_millisecond)
137
154
  end
138
155
  rescue
139
- def now_cpu
140
- 0
156
+ def now_cpu # rubocop:disable Lint/DuplicateMethods
157
+ 0.0
141
158
  end
142
159
  end
143
160
 
144
- if defined?(JRUBY_VERSION)
161
+ if GC.stat.key?(:total_allocated_objects)
145
162
  def now_allocations
146
- 0
163
+ GC.stat(:total_allocated_objects)
147
164
  end
148
- else
165
+ else # Likely on JRuby, TruffleRuby
149
166
  def now_allocations
150
- GC.stat :total_allocated_objects
167
+ 0
151
168
  end
152
169
  end
153
170
  end
@@ -2,10 +2,9 @@
2
2
 
3
3
  require "active_support/notifications/instrumenter"
4
4
  require "active_support/notifications/fanout"
5
- require "active_support/per_thread_registry"
6
5
 
7
6
  module ActiveSupport
8
- # = Notifications
7
+ # = \Notifications
9
8
  #
10
9
  # <tt>ActiveSupport::Notifications</tt> provides an instrumentation API for
11
10
  # Ruby.
@@ -85,7 +84,7 @@ module ActiveSupport
85
84
  # event.payload[:exception] # => ["ArgumentError", "Invalid value"]
86
85
  # event.payload[:exception_object] # => #<ArgumentError: Invalid value>
87
86
  #
88
- # As the earlier example depicts, the class <tt>ActiveSupport::Notifications::Event</tt>
87
+ # As the earlier example depicts, the class ActiveSupport::Notifications::Event
89
88
  # is able to take the arguments as they come and provide an object-oriented
90
89
  # interface to that data.
91
90
  #
@@ -198,6 +197,10 @@ module ActiveSupport
198
197
  notifier.publish(name, *args)
199
198
  end
200
199
 
200
+ def publish_event(event) # :nodoc:
201
+ notifier.publish_event(event)
202
+ end
203
+
201
204
  def instrument(name, payload = {})
202
205
  if notifier.listening?(name)
203
206
  instrumenter.instrument(name, payload) { yield payload if block_given? }
@@ -231,6 +234,12 @@ module ActiveSupport
231
234
  # ActiveSupport::Notifications.subscribe(/render/) do |event|
232
235
  # @event = event
233
236
  # end
237
+ #
238
+ # Raises an error if invalid event name type is passed:
239
+ #
240
+ # ActiveSupport::Notifications.subscribe(:render) {|*args| ...}
241
+ # #=> ArgumentError (pattern must be specified as a String, Regexp or empty)
242
+ #
234
243
  def subscribe(pattern = nil, callback = nil, &block)
235
244
  notifier.subscribe(pattern, callback, monotonic: false, &block)
236
245
  end
@@ -251,28 +260,13 @@ module ActiveSupport
251
260
  end
252
261
 
253
262
  def instrumenter
254
- InstrumentationRegistry.instance.instrumenter_for(notifier)
263
+ registry[notifier] ||= Instrumenter.new(notifier)
255
264
  end
256
- end
257
265
 
258
- # This class is a registry which holds all of the +Instrumenter+ objects
259
- # in a particular thread local. To access the +Instrumenter+ object for a
260
- # particular +notifier+, you can call the following method:
261
- #
262
- # InstrumentationRegistry.instrumenter_for(notifier)
263
- #
264
- # The instrumenters for multiple notifiers are held in a single instance of
265
- # this class.
266
- class InstrumentationRegistry # :nodoc:
267
- extend ActiveSupport::PerThreadRegistry
268
-
269
- def initialize
270
- @registry = {}
271
- end
272
-
273
- def instrumenter_for(notifier)
274
- @registry[notifier] ||= Instrumenter.new(notifier)
275
- end
266
+ private
267
+ def registry
268
+ ActiveSupport::IsolatedExecutionState[:active_support_notifications_registry] ||= {}
269
+ end
276
270
  end
277
271
 
278
272
  self.notifier = Fanout.new
@@ -174,9 +174,7 @@ module ActiveSupport
174
174
  end
175
175
 
176
176
  def valid_float?
177
- Float(number)
178
- rescue ArgumentError, TypeError
179
- false
177
+ Float(number, exception: false)
180
178
  end
181
179
  end
182
180
  end
@@ -8,16 +8,21 @@ module ActiveSupport
8
8
  self.namespace = :currency
9
9
 
10
10
  def convert
11
- number = self.number.to_s.strip
12
11
  format = options[:format]
13
12
 
14
- if number.sub!(/^-/, "") &&
15
- (options[:precision] != 0 || number.to_f > 0.5)
16
- format = options[:negative_format]
13
+ number_f = valid_float?
14
+ if number_f
15
+ if number_f.negative?
16
+ number_f = number_f.abs
17
+ format = options[:negative_format] if (number_f * 10**options[:precision]) >= 0.5
18
+ end
19
+ number_s = NumberToRoundedConverter.convert(number_f, options)
20
+ else
21
+ number_s = number.to_s.strip
22
+ format = options[:negative_format] if number_s.sub!(/^-/, "")
17
23
  end
18
24
 
19
- rounded_number = NumberToRoundedConverter.convert(number, options)
20
- format.gsub("%n", rounded_number).gsub("%u", options[:unit])
25
+ format.gsub("%n", number_s).gsub("%u", options[:unit])
21
26
  end
22
27
 
23
28
  private
@@ -4,7 +4,7 @@ require "active_support/number_helper/number_converter"
4
4
 
5
5
  module ActiveSupport
6
6
  module NumberHelper
7
- class NumberToDelimitedConverter < NumberConverter #:nodoc:
7
+ class NumberToDelimitedConverter < NumberConverter # :nodoc:
8
8
  self.validate_float = true
9
9
 
10
10
  DEFAULT_DELIMITER_REGEX = /(\d)(?=(\d\d\d)+(?!\d))/
@@ -4,7 +4,7 @@ require "active_support/number_helper/number_converter"
4
4
 
5
5
  module ActiveSupport
6
6
  module NumberHelper
7
- class NumberToHumanSizeConverter < NumberConverter #:nodoc:
7
+ class NumberToHumanSizeConverter < NumberConverter # :nodoc:
8
8
  STORAGE_UNITS = [:byte, :kb, :mb, :gb, :tb, :pb, :eb]
9
9
 
10
10
  self.namespace = :human
@@ -4,7 +4,7 @@ require "active_support/number_helper/number_converter"
4
4
 
5
5
  module ActiveSupport
6
6
  module NumberHelper
7
- class NumberToPhoneConverter < NumberConverter #:nodoc:
7
+ class NumberToPhoneConverter < NumberConverter # :nodoc:
8
8
  def convert
9
9
  str = country_code(opts[:country_code]).dup
10
10
  str << convert_to_phone_number(number.to_s.strip)
@@ -35,16 +35,12 @@ module ActiveSupport
35
35
  end
36
36
 
37
37
  def absolute_precision(number)
38
- if significant && options[:precision] > 0
38
+ if options[:significant] && options[:precision] > 0
39
39
  options[:precision] - digit_count(convert_to_decimal(number))
40
40
  else
41
41
  options[:precision]
42
42
  end
43
43
  end
44
-
45
- def significant
46
- options[:significant]
47
- end
48
44
  end
49
45
  end
50
46
  end
@@ -99,8 +99,6 @@ module ActiveSupport
99
99
  # number_to_currency(1234567890.506, locale: :fr) # => "1 234 567 890,51 €"
100
100
  # number_to_currency('123a456') # => "$123a456"
101
101
  #
102
- # number_to_currency("123a456", raise: true) # => InvalidNumberError
103
- #
104
102
  # number_to_currency(-0.456789, precision: 0)
105
103
  # # => "$0"
106
104
  # number_to_currency(-1234567890.50, negative_format: '(%u%n)')
@@ -1,10 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "active_support/core_ext/hash/deep_merge"
4
- require "active_support/core_ext/symbol/starts_ends_with"
5
4
 
6
5
  module ActiveSupport
7
- class OptionMerger #:nodoc:
6
+ class OptionMerger # :nodoc:
8
7
  instance_methods.each do |method|
9
8
  undef_method(method) unless method.start_with?("__", "instance_eval", "class", "object_id")
10
9
  end
@@ -25,22 +24,15 @@ module ActiveSupport
25
24
  options = @options
26
25
  end
27
26
 
28
- invoke_method(method, arguments, options, &block)
29
- end
30
-
31
- if RUBY_VERSION >= "2.7"
32
- def invoke_method(method, arguments, options, &block)
33
- if options
34
- @context.__send__(method, *arguments, **options, &block)
35
- else
36
- @context.__send__(method, *arguments, &block)
37
- end
38
- end
39
- else
40
- def invoke_method(method, arguments, options, &block)
41
- arguments << options.dup if options
27
+ if options
28
+ @context.__send__(method, *arguments, **options, &block)
29
+ else
42
30
  @context.__send__(method, *arguments, &block)
43
31
  end
44
32
  end
33
+
34
+ def respond_to_missing?(*arguments)
35
+ @context.respond_to?(*arguments)
36
+ end
45
37
  end
46
38
  end
@@ -21,7 +21,7 @@ module ActiveSupport
21
21
  #
22
22
  # <tt>ActiveSupport::OrderedHash</tt> is namespaced to prevent conflicts
23
23
  # with other implementations.
24
- class OrderedHash < ::Hash
24
+ class OrderedHash < ::Hash # :nodoc:
25
25
  def to_yaml_type
26
26
  "!tag:yaml.org,2002:omap"
27
27
  end
@@ -68,7 +68,7 @@ module ActiveSupport
68
68
  end
69
69
  end
70
70
 
71
- # +InheritableOptions+ provides a constructor to build an +OrderedOptions+
71
+ # +InheritableOptions+ provides a constructor to build an OrderedOptions
72
72
  # hash inherited from another hash.
73
73
  #
74
74
  # Use this if you already have some hash and you want to create a new one based on it.
@@ -16,6 +16,11 @@ module ActiveSupport
16
16
  # ActiveSupport::ParameterFilter.new([:foo, "bar"])
17
17
  # => replaces the value to all keys matching /foo|bar/i with "[FILTERED]"
18
18
  #
19
+ # ActiveSupport::ParameterFilter.new([/\Apin\z/i, /\Apin_/i])
20
+ # => replaces the value for the exact (case-insensitive) key 'pin' and all
21
+ # (case-insensitive) keys beginning with 'pin_', with "[FILTERED]".
22
+ # Does not match keys with 'pin' as a substring, such as 'shipping_id'.
23
+ #
19
24
  # ActiveSupport::ParameterFilter.new(["credit_card.code"])
20
25
  # => replaces { credit_card: {code: "xxxx"} } with "[FILTERED]", does not
21
26
  # change { file: { code: "xxxx"} }
@@ -40,6 +40,10 @@ module ActiveSupport
40
40
  # If the class has an initializer, it must accept no arguments.
41
41
  module PerThreadRegistry
42
42
  def self.extended(object)
43
+ ActiveSupport::Deprecation.warn(<<~MSG)
44
+ ActiveSupport::PerThreadRegistry is deprecated and will be removed in Rails 7.1.
45
+ Use `Module#thread_mattr_accessor` instead.
46
+ MSG
43
47
  object.instance_variable_set :@per_thread_registry_key, object.name.freeze
44
48
  end
45
49
 
@@ -56,6 +60,6 @@ module ActiveSupport
56
60
 
57
61
  send(name, *args, &block)
58
62
  end
59
- ruby2_keywords(:method_missing) if respond_to?(:ruby2_keywords, true)
63
+ ruby2_keywords(:method_missing)
60
64
  end
61
65
  end
@@ -6,9 +6,27 @@ 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
9
10
 
10
11
  config.eager_load_namespaces << ActiveSupport
11
12
 
13
+ initializer "active_support.isolation_level" do |app|
14
+ config.after_initialize do
15
+ if level = app.config.active_support.delete(:isolation_level)
16
+ ActiveSupport::IsolatedExecutionState.isolation_level = level
17
+ end
18
+ end
19
+ end
20
+
21
+ initializer "active_support.remove_deprecated_time_with_zone_name" do |app|
22
+ 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
+ end
27
+ end
28
+ end
29
+
12
30
  initializer "active_support.set_authenticated_message_encryption" do |app|
13
31
  config.after_initialize do
14
32
  unless app.config.active_support.use_authenticated_message_encryption.nil?
@@ -18,28 +36,48 @@ module ActiveSupport
18
36
  end
19
37
  end
20
38
 
39
+ initializer "active_support.reset_execution_context" do |app|
40
+ app.reloader.before_class_unload { ActiveSupport::ExecutionContext.clear }
41
+ app.executor.to_run { ActiveSupport::ExecutionContext.clear }
42
+ app.executor.to_complete { ActiveSupport::ExecutionContext.clear }
43
+ end
44
+
21
45
  initializer "active_support.reset_all_current_attributes_instances" do |app|
22
46
  app.reloader.before_class_unload { ActiveSupport::CurrentAttributes.clear_all }
23
47
  app.executor.to_run { ActiveSupport::CurrentAttributes.reset_all }
24
48
  app.executor.to_complete { ActiveSupport::CurrentAttributes.reset_all }
25
49
 
26
50
  ActiveSupport.on_load(:active_support_test_case) do
27
- require "active_support/current_attributes/test_helper"
28
- include ActiveSupport::CurrentAttributes::TestHelper
51
+ if app.config.active_support.executor_around_test_case
52
+ require "active_support/executor/test_helper"
53
+ include ActiveSupport::Executor::TestHelper
54
+ else
55
+ require "active_support/current_attributes/test_helper"
56
+ include ActiveSupport::CurrentAttributes::TestHelper
57
+
58
+ require "active_support/execution_context/test_helper"
59
+ include ActiveSupport::ExecutionContext::TestHelper
60
+ end
29
61
  end
30
62
  end
31
63
 
32
64
  initializer "active_support.deprecation_behavior" do |app|
33
- if deprecation = app.config.active_support.deprecation
34
- ActiveSupport::Deprecation.behavior = deprecation
35
- end
65
+ if app.config.active_support.report_deprecations == false
66
+ ActiveSupport::Deprecation.silenced = true
67
+ ActiveSupport::Deprecation.behavior = :silence
68
+ ActiveSupport::Deprecation.disallowed_behavior = :silence
69
+ else
70
+ if deprecation = app.config.active_support.deprecation
71
+ ActiveSupport::Deprecation.behavior = deprecation
72
+ end
36
73
 
37
- if disallowed_deprecation = app.config.active_support.disallowed_deprecation
38
- ActiveSupport::Deprecation.disallowed_behavior = disallowed_deprecation
39
- end
74
+ if disallowed_deprecation = app.config.active_support.disallowed_deprecation
75
+ ActiveSupport::Deprecation.disallowed_behavior = disallowed_deprecation
76
+ end
40
77
 
41
- if disallowed_warnings = app.config.active_support.disallowed_deprecation_warnings
42
- ActiveSupport::Deprecation.disallowed_warnings = disallowed_warnings
78
+ if disallowed_warnings = app.config.active_support.disallowed_deprecation_warnings
79
+ ActiveSupport::Deprecation.disallowed_warnings = disallowed_warnings
80
+ end
43
81
  end
44
82
  end
45
83
 
@@ -75,6 +113,10 @@ module ActiveSupport
75
113
  end
76
114
  end
77
115
 
116
+ initializer "active_support.set_error_reporter" do |app|
117
+ ActiveSupport.error_reporter = app.executor.error_reporter
118
+ end
119
+
78
120
  initializer "active_support.set_configs" do |app|
79
121
  app.config.active_support.each do |k, v|
80
122
  k = "#{k}="
@@ -84,19 +126,27 @@ module ActiveSupport
84
126
 
85
127
  initializer "active_support.set_hash_digest_class" do |app|
86
128
  config.after_initialize do
87
- if app.config.active_support.use_sha1_digests
88
- ActiveSupport::Deprecation.warn(<<-MSG.squish)
89
- config.active_support.use_sha1_digests is deprecated and will
90
- be removed from Rails 7.0. Use
91
- config.active_support.hash_digest_class = ::Digest::SHA1 instead.
92
- MSG
93
- ActiveSupport::Digest.hash_digest_class = ::Digest::SHA1
94
- end
95
-
96
129
  if klass = app.config.active_support.hash_digest_class
97
130
  ActiveSupport::Digest.hash_digest_class = klass
98
131
  end
99
132
  end
100
133
  end
134
+
135
+ initializer "active_support.set_key_generator_hash_digest_class" do |app|
136
+ config.after_initialize do
137
+ if klass = app.config.active_support.key_generator_hash_digest_class
138
+ ActiveSupport::KeyGenerator.hash_digest_class = klass
139
+ end
140
+ end
141
+ end
142
+
143
+ initializer "active_support.set_rfc4122_namespaced_uuids" do |app|
144
+ 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
148
+ end
149
+ end
150
+ end
101
151
  end
102
152
  end
@@ -74,7 +74,7 @@ module ActiveSupport
74
74
  # Matches an exception to a handler based on the exception class.
75
75
  #
76
76
  # If no handler matches the exception, check for a handler matching the
77
- # (optional) exception.cause. If no handler matches the exception or its
77
+ # (optional) +exception.cause+. If no handler matches the exception or its
78
78
  # cause, this returns +nil+, so you can deal with unhandled exceptions.
79
79
  # Be sure to re-raise unhandled exceptions if this is what you expect.
80
80
  #
@@ -100,7 +100,7 @@ module ActiveSupport
100
100
  end
101
101
  end
102
102
 
103
- def handler_for_rescue(exception, object: self) #:nodoc:
103
+ def handler_for_rescue(exception, object: self) # :nodoc:
104
104
  case rescuer = find_rescue_handler(exception)
105
105
  when Symbol
106
106
  method = object.method(rescuer)
@@ -160,14 +160,14 @@ module ActiveSupport
160
160
  end
161
161
 
162
162
  # Delegates to the class method, but uses the instance as the subject for
163
- # rescue_from handlers (method calls, instance_exec blocks).
163
+ # rescue_from handlers (method calls, +instance_exec+ blocks).
164
164
  def rescue_with_handler(exception)
165
165
  self.class.rescue_with_handler exception, object: self
166
166
  end
167
167
 
168
168
  # Internal handler lookup. Delegates to class method. Some libraries call
169
169
  # this directly, so keeping it around for compatibility.
170
- def handler_for_rescue(exception) #:nodoc:
170
+ def handler_for_rescue(exception) # :nodoc:
171
171
  self.class.handler_for_rescue exception, object: self
172
172
  end
173
173
  end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveSupport
4
+ module RubyFeatures # :nodoc:
5
+ CLASS_SUBCLASSES = Class.method_defined?(:subclasses) # RUBY_VERSION >= "3.1"
6
+ end
7
+ end
@@ -4,7 +4,7 @@ require "active_support/security_utils"
4
4
  require "active_support/messages/rotator"
5
5
 
6
6
  module ActiveSupport
7
- # The ActiveSupport::SecureCompareRotator is a wrapper around +ActiveSupport::SecurityUtils.secure_compare+
7
+ # The ActiveSupport::SecureCompareRotator is a wrapper around ActiveSupport::SecurityUtils.secure_compare
8
8
  # and allows you to rotate a previously defined value to a new one.
9
9
  #
10
10
  # It can be used as follow:
@@ -17,7 +17,7 @@ module ActiveSupport
17
17
  #
18
18
  # class MyController < ApplicationController
19
19
  # def authenticate_request
20
- # rotator = ActiveSupport::SecureComparerotator.new('new_password')
20
+ # rotator = ActiveSupport::SecureCompareRotator.new('new_password')
21
21
  # rotator.rotate('old_password')
22
22
  #
23
23
  # authenticate_or_request_with_http_basic do |username, password|
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "active_support/core_ext/symbol/starts_ends_with"
4
-
5
3
  module ActiveSupport
6
4
  # Wrapping a string in this class gives you a prettier way to test
7
5
  # for equality. The value returned by <tt>Rails.env</tt> is wrapped
@@ -1,6 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "active_support/per_thread_registry"
4
3
  require "active_support/notifications"
5
4
 
6
5
  module ActiveSupport
@@ -150,25 +149,15 @@ module ActiveSupport
150
149
  send(method, event)
151
150
  end
152
151
 
152
+ def publish_event(event) # :nodoc:
153
+ method = event.name.split(".").first
154
+ send(method, event)
155
+ end
156
+
153
157
  private
154
158
  def event_stack
155
- SubscriberQueueRegistry.instance.get_queue(@queue_key)
159
+ registry = ActiveSupport::IsolatedExecutionState[:active_support_subscriber_queue_registry] ||= {}
160
+ registry[@queue_key] ||= []
156
161
  end
157
162
  end
158
-
159
- # This is a registry for all the event stacks kept for subscribers.
160
- #
161
- # See the documentation of <tt>ActiveSupport::PerThreadRegistry</tt>
162
- # for further details.
163
- class SubscriberQueueRegistry # :nodoc:
164
- extend PerThreadRegistry
165
-
166
- def initialize
167
- @registry = {}
168
- end
169
-
170
- def get_queue(queue_key)
171
- @registry[queue_key] ||= []
172
- end
173
- end
174
163
  end
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "active_support/core_ext/module/delegation"
4
+ require "active_support/core_ext/module/redefine_method"
4
5
  require "active_support/core_ext/object/blank"
5
6
  require "logger"
6
7
  require "active_support/logger"
@@ -57,7 +58,7 @@ module ActiveSupport
57
58
  def current_tags
58
59
  # We use our object ID here to avoid conflicting with other instances
59
60
  thread_key = @thread_key ||= "activesupport_tagged_logging_tags:#{object_id}"
60
- Thread.current[thread_key] ||= []
61
+ IsolatedExecutionState[thread_key] ||= []
61
62
  end
62
63
 
63
64
  def tags_text
@@ -94,6 +95,20 @@ module ActiveSupport
94
95
 
95
96
  delegate :push_tags, :pop_tags, :clear_tags!, to: :formatter
96
97
 
98
+ def broadcast_to(other_logger) # :nodoc:
99
+ define_singleton_method(:formatter=) do |formatter|
100
+ other_logger.formatter ||= formatter
101
+
102
+ other_logger.formatter.singleton_class.redefine_method(:current_tags) do
103
+ formatter.current_tags
104
+ end
105
+
106
+ super(formatter)
107
+ end
108
+
109
+ self.formatter = self.formatter.clone
110
+ end
111
+
97
112
  def tagged(*tags)
98
113
  if block_given?
99
114
  formatter.tagged(*tags) { yield self }