activesupport 6.1.0 → 7.0.4.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 (183) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +263 -352
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +1 -1
  5. data/lib/active_support/actionable_error.rb +1 -1
  6. data/lib/active_support/array_inquirer.rb +0 -2
  7. data/lib/active_support/backtrace_cleaner.rb +2 -2
  8. data/lib/active_support/benchmarkable.rb +2 -2
  9. data/lib/active_support/cache/file_store.rb +16 -10
  10. data/lib/active_support/cache/mem_cache_store.rb +154 -39
  11. data/lib/active_support/cache/memory_store.rb +24 -16
  12. data/lib/active_support/cache/null_store.rb +10 -2
  13. data/lib/active_support/cache/redis_cache_store.rb +59 -78
  14. data/lib/active_support/cache/strategy/local_cache.rb +38 -61
  15. data/lib/active_support/cache.rb +306 -148
  16. data/lib/active_support/callbacks.rb +184 -85
  17. data/lib/active_support/code_generator.rb +65 -0
  18. data/lib/active_support/concern.rb +5 -5
  19. data/lib/active_support/concurrency/load_interlock_aware_monitor.rb +2 -4
  20. data/lib/active_support/concurrency/share_lock.rb +2 -2
  21. data/lib/active_support/configurable.rb +8 -5
  22. data/lib/active_support/configuration_file.rb +7 -2
  23. data/lib/active_support/core_ext/array/access.rb +1 -5
  24. data/lib/active_support/core_ext/array/conversions.rb +13 -12
  25. data/lib/active_support/core_ext/array/deprecated_conversions.rb +25 -0
  26. data/lib/active_support/core_ext/array/grouping.rb +6 -6
  27. data/lib/active_support/core_ext/array/inquiry.rb +2 -2
  28. data/lib/active_support/core_ext/array.rb +1 -0
  29. data/lib/active_support/core_ext/big_decimal/conversions.rb +1 -1
  30. data/lib/active_support/core_ext/class/subclasses.rb +25 -17
  31. data/lib/active_support/core_ext/date/blank.rb +1 -1
  32. data/lib/active_support/core_ext/date/calculations.rb +9 -9
  33. data/lib/active_support/core_ext/date/conversions.rb +14 -14
  34. data/lib/active_support/core_ext/date/deprecated_conversions.rb +26 -0
  35. data/lib/active_support/core_ext/date.rb +1 -0
  36. data/lib/active_support/core_ext/date_and_time/calculations.rb +4 -4
  37. data/lib/active_support/core_ext/date_and_time/compatibility.rb +1 -1
  38. data/lib/active_support/core_ext/date_time/blank.rb +1 -1
  39. data/lib/active_support/core_ext/date_time/conversions.rb +13 -13
  40. data/lib/active_support/core_ext/date_time/deprecated_conversions.rb +22 -0
  41. data/lib/active_support/core_ext/date_time.rb +1 -0
  42. data/lib/active_support/core_ext/digest/uuid.rb +39 -13
  43. data/lib/active_support/core_ext/enumerable.rb +101 -32
  44. data/lib/active_support/core_ext/file/atomic.rb +3 -1
  45. data/lib/active_support/core_ext/hash/conversions.rb +0 -1
  46. data/lib/active_support/core_ext/hash/indifferent_access.rb +3 -3
  47. data/lib/active_support/core_ext/hash/keys.rb +1 -1
  48. data/lib/active_support/core_ext/kernel/reporting.rb +4 -4
  49. data/lib/active_support/core_ext/kernel/singleton_class.rb +1 -1
  50. data/lib/active_support/core_ext/module/attribute_accessors.rb +2 -0
  51. data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +19 -10
  52. data/lib/active_support/core_ext/module/delegation.rb +2 -8
  53. data/lib/active_support/core_ext/name_error.rb +2 -8
  54. data/lib/active_support/core_ext/numeric/conversions.rb +80 -77
  55. data/lib/active_support/core_ext/numeric/deprecated_conversions.rb +60 -0
  56. data/lib/active_support/core_ext/numeric.rb +1 -0
  57. data/lib/active_support/core_ext/object/acts_like.rb +29 -5
  58. data/lib/active_support/core_ext/object/blank.rb +2 -2
  59. data/lib/active_support/core_ext/object/deep_dup.rb +1 -1
  60. data/lib/active_support/core_ext/object/duplicable.rb +11 -0
  61. data/lib/active_support/core_ext/object/json.rb +37 -25
  62. data/lib/active_support/core_ext/object/to_query.rb +2 -2
  63. data/lib/active_support/core_ext/object/try.rb +20 -20
  64. data/lib/active_support/core_ext/object/with_options.rb +20 -1
  65. data/lib/active_support/core_ext/pathname/existence.rb +21 -0
  66. data/lib/active_support/core_ext/pathname.rb +3 -0
  67. data/lib/active_support/core_ext/range/compare_range.rb +0 -25
  68. data/lib/active_support/core_ext/range/conversions.rb +8 -8
  69. data/lib/active_support/core_ext/range/deprecated_conversions.rb +26 -0
  70. data/lib/active_support/core_ext/range/each.rb +1 -1
  71. data/lib/active_support/core_ext/range/include_time_with_zone.rb +4 -25
  72. data/lib/active_support/core_ext/range/overlaps.rb +1 -1
  73. data/lib/active_support/core_ext/range.rb +1 -1
  74. data/lib/active_support/core_ext/securerandom.rb +1 -1
  75. data/lib/active_support/core_ext/string/conversions.rb +2 -2
  76. data/lib/active_support/core_ext/string/filters.rb +1 -1
  77. data/lib/active_support/core_ext/string/inflections.rb +1 -1
  78. data/lib/active_support/core_ext/string/inquiry.rb +1 -1
  79. data/lib/active_support/core_ext/string/output_safety.rb +91 -39
  80. data/lib/active_support/core_ext/symbol/starts_ends_with.rb +0 -8
  81. data/lib/active_support/core_ext/time/calculations.rb +9 -7
  82. data/lib/active_support/core_ext/time/conversions.rb +14 -12
  83. data/lib/active_support/core_ext/time/deprecated_conversions.rb +22 -0
  84. data/lib/active_support/core_ext/time/zones.rb +7 -22
  85. data/lib/active_support/core_ext/time.rb +1 -0
  86. data/lib/active_support/core_ext/uri.rb +3 -27
  87. data/lib/active_support/core_ext.rb +2 -1
  88. data/lib/active_support/current_attributes.rb +32 -14
  89. data/lib/active_support/dependencies/interlock.rb +10 -18
  90. data/lib/active_support/dependencies/require_dependency.rb +28 -0
  91. data/lib/active_support/dependencies.rb +58 -788
  92. data/lib/active_support/deprecation/behaviors.rb +8 -5
  93. data/lib/active_support/deprecation/method_wrappers.rb +3 -3
  94. data/lib/active_support/deprecation/proxy_wrappers.rb +2 -2
  95. data/lib/active_support/deprecation.rb +2 -2
  96. data/lib/active_support/descendants_tracker.rb +174 -68
  97. data/lib/active_support/digest.rb +5 -3
  98. data/lib/active_support/duration/iso8601_parser.rb +3 -3
  99. data/lib/active_support/duration/iso8601_serializer.rb +9 -1
  100. data/lib/active_support/duration.rb +81 -51
  101. data/lib/active_support/encrypted_configuration.rb +13 -2
  102. data/lib/active_support/encrypted_file.rb +13 -1
  103. data/lib/active_support/environment_inquirer.rb +1 -1
  104. data/lib/active_support/error_reporter.rb +117 -0
  105. data/lib/active_support/evented_file_update_checker.rb +3 -5
  106. data/lib/active_support/execution_context/test_helper.rb +13 -0
  107. data/lib/active_support/execution_context.rb +53 -0
  108. data/lib/active_support/execution_wrapper.rb +43 -21
  109. data/lib/active_support/executor/test_helper.rb +7 -0
  110. data/lib/active_support/fork_tracker.rb +19 -10
  111. data/lib/active_support/gem_version.rb +5 -5
  112. data/lib/active_support/hash_with_indifferent_access.rb +9 -2
  113. data/lib/active_support/html_safe_translation.rb +43 -0
  114. data/lib/active_support/i18n.rb +1 -0
  115. data/lib/active_support/i18n_railtie.rb +1 -1
  116. data/lib/active_support/inflector/inflections.rb +23 -7
  117. data/lib/active_support/inflector/methods.rb +24 -48
  118. data/lib/active_support/inflector/transliterate.rb +1 -1
  119. data/lib/active_support/isolated_execution_state.rb +72 -0
  120. data/lib/active_support/json/encoding.rb +3 -3
  121. data/lib/active_support/key_generator.rb +22 -5
  122. data/lib/active_support/lazy_load_hooks.rb +28 -4
  123. data/lib/active_support/locale/en.yml +2 -2
  124. data/lib/active_support/log_subscriber/test_helper.rb +2 -2
  125. data/lib/active_support/log_subscriber.rb +15 -5
  126. data/lib/active_support/logger_thread_safe_level.rb +4 -13
  127. data/lib/active_support/message_encryptor.rb +12 -6
  128. data/lib/active_support/message_verifier.rb +46 -14
  129. data/lib/active_support/messages/metadata.rb +2 -2
  130. data/lib/active_support/multibyte/chars.rb +10 -11
  131. data/lib/active_support/multibyte/unicode.rb +0 -12
  132. data/lib/active_support/multibyte.rb +1 -1
  133. data/lib/active_support/notifications/fanout.rb +91 -65
  134. data/lib/active_support/notifications/instrumenter.rb +32 -15
  135. data/lib/active_support/notifications.rb +24 -24
  136. data/lib/active_support/number_helper/number_converter.rb +1 -3
  137. data/lib/active_support/number_helper/number_to_currency_converter.rb +11 -6
  138. data/lib/active_support/number_helper/number_to_delimited_converter.rb +1 -1
  139. data/lib/active_support/number_helper/number_to_human_size_converter.rb +1 -1
  140. data/lib/active_support/number_helper/number_to_phone_converter.rb +1 -1
  141. data/lib/active_support/number_helper/number_to_rounded_converter.rb +10 -6
  142. data/lib/active_support/number_helper/rounding_helper.rb +2 -6
  143. data/lib/active_support/number_helper.rb +0 -2
  144. data/lib/active_support/option_merger.rb +10 -18
  145. data/lib/active_support/ordered_hash.rb +1 -1
  146. data/lib/active_support/ordered_options.rb +1 -1
  147. data/lib/active_support/parameter_filter.rb +6 -1
  148. data/lib/active_support/per_thread_registry.rb +5 -0
  149. data/lib/active_support/railtie.rb +69 -19
  150. data/lib/active_support/reloader.rb +1 -1
  151. data/lib/active_support/rescuable.rb +16 -16
  152. data/lib/active_support/ruby_features.rb +7 -0
  153. data/lib/active_support/secure_compare_rotator.rb +2 -2
  154. data/lib/active_support/security_utils.rb +1 -1
  155. data/lib/active_support/string_inquirer.rb +0 -2
  156. data/lib/active_support/subscriber.rb +7 -18
  157. data/lib/active_support/tagged_logging.rb +2 -2
  158. data/lib/active_support/test_case.rb +13 -21
  159. data/lib/active_support/testing/assertions.rb +36 -6
  160. data/lib/active_support/testing/deprecation.rb +52 -1
  161. data/lib/active_support/testing/isolation.rb +2 -2
  162. data/lib/active_support/testing/method_call_assertions.rb +5 -5
  163. data/lib/active_support/testing/parallelization/server.rb +4 -0
  164. data/lib/active_support/testing/parallelization/worker.rb +3 -0
  165. data/lib/active_support/testing/parallelization.rb +4 -0
  166. data/lib/active_support/testing/parallelize_executor.rb +76 -0
  167. data/lib/active_support/testing/stream.rb +3 -5
  168. data/lib/active_support/testing/tagged_logging.rb +1 -1
  169. data/lib/active_support/testing/time_helpers.rb +13 -2
  170. data/lib/active_support/time_with_zone.rb +60 -20
  171. data/lib/active_support/values/time_zone.rb +36 -15
  172. data/lib/active_support/version.rb +1 -1
  173. data/lib/active_support/xml_mini/jdom.rb +1 -1
  174. data/lib/active_support/xml_mini/libxml.rb +5 -5
  175. data/lib/active_support/xml_mini/libxmlsax.rb +1 -1
  176. data/lib/active_support/xml_mini/nokogiri.rb +4 -4
  177. data/lib/active_support/xml_mini/nokogirisax.rb +1 -1
  178. data/lib/active_support/xml_mini/rexml.rb +1 -1
  179. data/lib/active_support/xml_mini.rb +5 -4
  180. data/lib/active_support.rb +17 -1
  181. metadata +29 -26
  182. data/lib/active_support/core_ext/marshal.rb +0 -26
  183. data/lib/active_support/dependencies/zeitwerk_integration.rb +0 -117
@@ -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
  #
@@ -178,7 +177,7 @@ module ActiveSupport
178
177
  #
179
178
  # Subscribers using a regexp or other pattern-matching object will remain subscribed
180
179
  # to all events that match their original pattern, unless those events match a string
181
- # passed to `unsubscribe`:
180
+ # passed to +unsubscribe+:
182
181
  #
183
182
  # subscriber = ActiveSupport::Notifications.subscribe(/render/) { }
184
183
  # ActiveSupport::Notifications.unsubscribe('render_template.action_view')
@@ -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,10 +234,22 @@ 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
237
246
 
247
+ # Performs the same functionality as #subscribe, but the +start+ and
248
+ # +finish+ block arguments are in monotonic time instead of wall-clock
249
+ # time. Monotonic time will not jump forward or backward (due to NTP or
250
+ # Daylights Savings). Use +monotonic_subscribe+ when accuracy of time
251
+ # duration is important. For example, computing elapsed time between
252
+ # two events.
238
253
  def monotonic_subscribe(pattern = nil, callback = nil, &block)
239
254
  notifier.subscribe(pattern, callback, monotonic: true, &block)
240
255
  end
@@ -251,28 +266,13 @@ module ActiveSupport
251
266
  end
252
267
 
253
268
  def instrumenter
254
- InstrumentationRegistry.instance.instrumenter_for(notifier)
269
+ registry[notifier] ||= Instrumenter.new(notifier)
255
270
  end
256
- end
257
271
 
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
272
+ private
273
+ def registry
274
+ ActiveSupport::IsolatedExecutionState[:active_support_notifications_registry] ||= {}
275
+ end
276
276
  end
277
277
 
278
278
  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)
@@ -20,14 +20,18 @@ module ActiveSupport
20
20
  end
21
21
 
22
22
  formatted_string =
23
- if rounded_number.nan? || rounded_number.infinite? || rounded_number == rounded_number.to_i
24
- "%00.#{precision}f" % rounded_number
25
- else
23
+ if rounded_number.finite?
26
24
  s = rounded_number.to_s("F")
27
- s << "0" * precision
28
25
  a, b = s.split(".", 2)
29
- a << "."
30
- a << b[0, precision]
26
+ if precision != 0
27
+ b << "0" * precision
28
+ a << "."
29
+ a << b[0, precision]
30
+ end
31
+ a
32
+ else
33
+ # Infinity/NaN
34
+ "%f" % rounded_number
31
35
  end
32
36
  else
33
37
  formatted_string = rounded_number
@@ -13,7 +13,7 @@ module ActiveSupport
13
13
  precision = absolute_precision(number)
14
14
  return number unless precision
15
15
 
16
- rounded_number = convert_to_decimal(number).round(precision, options.fetch(:round_mode, :default))
16
+ rounded_number = convert_to_decimal(number).round(precision, options.fetch(:round_mode, :default).to_sym)
17
17
  rounded_number.zero? ? rounded_number.abs : rounded_number # prevent showing negative zeros
18
18
  end
19
19
 
@@ -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
@@ -16,8 +15,8 @@ module ActiveSupport
16
15
  private
17
16
  def method_missing(method, *arguments, &block)
18
17
  options = nil
19
- if arguments.first.is_a?(Proc)
20
- proc = arguments.pop
18
+ if arguments.size == 1 && arguments.first.is_a?(Proc)
19
+ proc = arguments.shift
21
20
  arguments << lambda { |*args| @options.deep_merge(proc.call(*args)) }
22
21
  elsif arguments.last.respond_to?(:to_hash)
23
22
  options = @options.deep_merge(arguments.pop)
@@ -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"} }
@@ -33,7 +38,7 @@ module ActiveSupport
33
38
  #
34
39
  # ==== Options
35
40
  #
36
- # * <tt>:mask</tt> - A replaced object when filtered. Defaults to +"[FILTERED]"+
41
+ # * <tt>:mask</tt> - A replaced object when filtered. Defaults to <tt>"[FILTERED]"</tt>.
37
42
  def initialize(filters = [], mask: FILTERED)
38
43
  @filters = filters
39
44
  @mask = mask
@@ -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,5 +60,6 @@ module ActiveSupport
56
60
 
57
61
  send(name, *args, &block)
58
62
  end
63
+ ruby2_keywords(:method_missing)
59
64
  end
60
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 6.2. 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
@@ -58,7 +58,7 @@ module ActiveSupport
58
58
  prepare!
59
59
  end
60
60
 
61
- def self.run! # :nodoc:
61
+ def self.run!(reset: false) # :nodoc:
62
62
  if check!
63
63
  super
64
64
  else