activesupport 7.1.1 → 7.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +67 -0
- data/lib/active_support/broadcast_logger.rb +8 -0
- data/lib/active_support/cache/entry.rb +7 -1
- data/lib/active_support/cache/file_store.rb +1 -1
- data/lib/active_support/cache/mem_cache_store.rb +10 -2
- data/lib/active_support/cache/redis_cache_store.rb +5 -2
- data/lib/active_support/cache.rb +19 -2
- data/lib/active_support/core_ext/date/conversions.rb +1 -1
- data/lib/active_support/core_ext/module/concerning.rb +6 -6
- data/lib/active_support/gem_version.rb +1 -1
- data/lib/active_support/inflector/methods.rb +2 -2
- data/lib/active_support/log_subscriber.rb +8 -2
- data/lib/active_support/messages/metadata.rb +1 -1
- data/lib/active_support/notifications/fanout.rb +25 -19
- data/lib/active_support/number_helper/number_to_human_size_converter.rb +2 -2
- data/lib/active_support/ordered_options.rb +2 -2
- data/lib/active_support/testing/strict_warnings.rb +1 -0
- data/lib/active_support/testing/time_helpers.rb +1 -1
- metadata +5 -5
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: 6db71966858e675d32617069b0df8dc17b1c5dfe8123c87ae96a28fdb6e2f5e6
         | 
| 4 | 
            +
              data.tar.gz: 81ffe410567130147cd0c6f74943d40404a4031b2cf30f12bfaa2ee698cd5a57
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: 99a9131ff9f97e739719621df9ba0a33d3b2fad9b1315397382235f29d33ee130f701d0c0ed767eacf01ccb31607eb26d7f5bb95f37ad86ac57f18817cd9b253
         | 
| 7 | 
            +
              data.tar.gz: ffa6a0ffe90b88c87f65d85ddb32390d20f8c34ab2517f797c34d325839cbf434a0202650cdd54f118bee9a299cf478f83af4222c313f2746e267bbd19003914
         | 
    
        data/CHANGELOG.md
    CHANGED
    
    | @@ -1,3 +1,70 @@ | |
| 1 | 
            +
            ## Rails 7.1.2 (November 10, 2023) ##
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            *   Fix `:expires_in` option for `RedisCacheStore#write_multi`.
         | 
| 4 | 
            +
             | 
| 5 | 
            +
                *fatkodima*
         | 
| 6 | 
            +
             | 
| 7 | 
            +
            *   Fix deserialization of non-string "purpose" field in Message serializer
         | 
| 8 | 
            +
             | 
| 9 | 
            +
                *Jacopo Beschi*
         | 
| 10 | 
            +
             | 
| 11 | 
            +
            *   Prevent global cache options being overwritten when setting dynamic options
         | 
| 12 | 
            +
                inside a `ActiveSupport::Cache::Store#fetch` block.
         | 
| 13 | 
            +
             | 
| 14 | 
            +
                *Yasha Krasnou*
         | 
| 15 | 
            +
             | 
| 16 | 
            +
            *   Fix missing `require` resulting in `NoMethodError` when running
         | 
| 17 | 
            +
                `bin/rails secrets:show` or `bin/rails secrets:edit`.
         | 
| 18 | 
            +
             | 
| 19 | 
            +
                *Stephen Ierodiaconou*
         | 
| 20 | 
            +
             | 
| 21 | 
            +
            *   Ensure `{down,up}case_first` returns non-frozen string.
         | 
| 22 | 
            +
             | 
| 23 | 
            +
                *Jonathan Hefner*
         | 
| 24 | 
            +
             | 
| 25 | 
            +
            *   Fix `#to_fs(:human_size)` to correctly work with negative numbers.
         | 
| 26 | 
            +
             | 
| 27 | 
            +
                *Earlopain*
         | 
| 28 | 
            +
             | 
| 29 | 
            +
            *   Fix `BroadcastLogger#dup` so that it duplicates the logger's `broadcasts`.
         | 
| 30 | 
            +
             | 
| 31 | 
            +
                *Andrew Novoselac*
         | 
| 32 | 
            +
             | 
| 33 | 
            +
            *   Fix issue where `bootstrap.rb` overwrites the `level` of a `BroadcastLogger`'s `broadcasts`.
         | 
| 34 | 
            +
             | 
| 35 | 
            +
                *Andrew Novoselac*
         | 
| 36 | 
            +
             | 
| 37 | 
            +
            *   Fix `ActiveSupport::Cache` to handle outdated Marshal payload from Rails 6.1 format.
         | 
| 38 | 
            +
             | 
| 39 | 
            +
                Active Support's Cache is supposed to treat a Marshal payload that can no longer be
         | 
| 40 | 
            +
                deserialized as a cache miss. It fail to do so for compressed payload in the Rails 6.1
         | 
| 41 | 
            +
                legacy format.
         | 
| 42 | 
            +
             | 
| 43 | 
            +
                *Jean Boussier*
         | 
| 44 | 
            +
             | 
| 45 | 
            +
            *   Fix `OrderedOptions#dig` for array indexes.
         | 
| 46 | 
            +
             | 
| 47 | 
            +
                *fatkodima*
         | 
| 48 | 
            +
             | 
| 49 | 
            +
            *   Fix time travel helpers to work when nested using with separate classes.
         | 
| 50 | 
            +
             | 
| 51 | 
            +
                *fatkodima*
         | 
| 52 | 
            +
             | 
| 53 | 
            +
            *   Fix `delete_matched` for file cache store to work with keys longer than the
         | 
| 54 | 
            +
                max filename size.
         | 
| 55 | 
            +
             | 
| 56 | 
            +
                *fatkodima* and *Jonathan Hefner*
         | 
| 57 | 
            +
             | 
| 58 | 
            +
            *   Fix compatibility with the `semantic_logger` gem.
         | 
| 59 | 
            +
             | 
| 60 | 
            +
                The `semantic_logger` gem doesn't behave exactly like stdlib logger in that
         | 
| 61 | 
            +
                `SemanticLogger#level` returns a Symbol while stdlib `Logger#level` returns an Integer.
         | 
| 62 | 
            +
             | 
| 63 | 
            +
                This caused the various `LogSubscriber` classes in Rails to break when assigned a
         | 
| 64 | 
            +
                `SemanticLogger` instance.
         | 
| 65 | 
            +
             | 
| 66 | 
            +
                *Jean Boussier*, *ojab*
         | 
| 67 | 
            +
             | 
| 1 68 | 
             
            ## Rails 7.1.1 (October 11, 2023) ##
         | 
| 2 69 |  | 
| 3 70 | 
             
            *   Add support for keyword arguments when delegating calls to custom loggers from `ActiveSupport::BroadcastLogger`.
         | 
| @@ -218,6 +218,14 @@ module ActiveSupport | |
| 218 218 | 
             
                  dispatch { |logger| logger.fatal! }
         | 
| 219 219 | 
             
                end
         | 
| 220 220 |  | 
| 221 | 
            +
                def initialize_copy(other)
         | 
| 222 | 
            +
                  @broadcasts = []
         | 
| 223 | 
            +
                  @progname = other.progname.dup
         | 
| 224 | 
            +
                  @formatter = other.formatter.dup
         | 
| 225 | 
            +
             | 
| 226 | 
            +
                  broadcast_to(*other.broadcasts.map(&:dup))
         | 
| 227 | 
            +
                end
         | 
| 228 | 
            +
             | 
| 221 229 | 
             
                private
         | 
| 222 230 | 
             
                  def dispatch(&block)
         | 
| 223 231 | 
             
                    @broadcasts.each { |logger| block.call(logger) }
         | 
| @@ -121,7 +121,13 @@ module ActiveSupport | |
| 121 121 |  | 
| 122 122 | 
             
                  private
         | 
| 123 123 | 
             
                    def uncompress(value)
         | 
| 124 | 
            -
                       | 
| 124 | 
            +
                      marshal_load(Zlib::Inflate.inflate(value))
         | 
| 125 | 
            +
                    end
         | 
| 126 | 
            +
             | 
| 127 | 
            +
                    def marshal_load(payload)
         | 
| 128 | 
            +
                      Marshal.load(payload)
         | 
| 129 | 
            +
                    rescue ArgumentError => error
         | 
| 130 | 
            +
                      raise Cache::DeserializationError, error.message
         | 
| 125 131 | 
             
                    end
         | 
| 126 132 | 
             
                end
         | 
| 127 133 | 
             
              end
         | 
| @@ -176,7 +176,7 @@ module ActiveSupport | |
| 176 176 |  | 
| 177 177 | 
             
                    # Translate a file path into a key.
         | 
| 178 178 | 
             
                    def file_path_key(path)
         | 
| 179 | 
            -
                      fname = path[cache_path.to_s.size..-1].split(File::SEPARATOR, 4).last
         | 
| 179 | 
            +
                      fname = path[cache_path.to_s.size..-1].split(File::SEPARATOR, 4).last.delete(File::SEPARATOR)
         | 
| 180 180 | 
             
                      URI.decode_www_form_component(fname, Encoding::UTF_8)
         | 
| 181 181 | 
             
                    end
         | 
| 182 182 |  | 
| @@ -270,14 +270,22 @@ module ActiveSupport | |
| 270 270 | 
             
                    def read_multi_entries(names, **options)
         | 
| 271 271 | 
             
                      keys_to_names = names.index_by { |name| normalize_key(name, options) }
         | 
| 272 272 |  | 
| 273 | 
            -
                      raw_values =  | 
| 273 | 
            +
                      raw_values = begin
         | 
| 274 | 
            +
                        @data.with { |c| c.get_multi(keys_to_names.keys) }
         | 
| 275 | 
            +
                      rescue Dalli::UnmarshalError
         | 
| 276 | 
            +
                        {}
         | 
| 277 | 
            +
                      end
         | 
| 278 | 
            +
             | 
| 274 279 | 
             
                      values = {}
         | 
| 275 280 |  | 
| 276 281 | 
             
                      raw_values.each do |key, value|
         | 
| 277 282 | 
             
                        entry = deserialize_entry(value, raw: options[:raw])
         | 
| 278 283 |  | 
| 279 284 | 
             
                        unless entry.nil? || entry.expired? || entry.mismatched?(normalize_version(keys_to_names[key], options))
         | 
| 280 | 
            -
                           | 
| 285 | 
            +
                          begin
         | 
| 286 | 
            +
                            values[keys_to_names[key]] = entry.value
         | 
| 287 | 
            +
                          rescue DeserializationError
         | 
| 288 | 
            +
                          end
         | 
| 281 289 | 
             
                        end
         | 
| 282 290 | 
             
                      end
         | 
| 283 291 |  | 
| @@ -332,7 +332,10 @@ module ActiveSupport | |
| 332 332 | 
             
                        if value
         | 
| 333 333 | 
             
                          entry = deserialize_entry(value, raw: raw)
         | 
| 334 334 | 
             
                          unless entry.nil? || entry.expired? || entry.mismatched?(normalize_version(name, options))
         | 
| 335 | 
            -
                             | 
| 335 | 
            +
                            begin
         | 
| 336 | 
            +
                              results[name] = entry.value
         | 
| 337 | 
            +
                            rescue DeserializationError
         | 
| 338 | 
            +
                            end
         | 
| 336 339 | 
             
                          end
         | 
| 337 340 | 
             
                        end
         | 
| 338 341 | 
             
                      end
         | 
| @@ -383,7 +386,7 @@ module ActiveSupport | |
| 383 386 | 
             
                    end
         | 
| 384 387 |  | 
| 385 388 | 
             
                    # Nonstandard store provider API to write multiple values at once.
         | 
| 386 | 
            -
                    def write_multi_entries(entries,  | 
| 389 | 
            +
                    def write_multi_entries(entries, **options)
         | 
| 387 390 | 
             
                      return if entries.empty?
         | 
| 388 391 |  | 
| 389 392 | 
             
                      failsafe :write_multi_entries do
         | 
    
        data/lib/active_support/cache.rb
    CHANGED
    
    | @@ -459,7 +459,17 @@ module ActiveSupport | |
| 459 459 | 
             
                        instrument(:read, name, options) do |payload|
         | 
| 460 460 | 
             
                          cached_entry = read_entry(key, **options, event: payload)
         | 
| 461 461 | 
             
                          entry = handle_expired_entry(cached_entry, key, options)
         | 
| 462 | 
            -
                           | 
| 462 | 
            +
                          if entry
         | 
| 463 | 
            +
                            if entry.mismatched?(normalize_version(name, options))
         | 
| 464 | 
            +
                              entry = nil
         | 
| 465 | 
            +
                            else
         | 
| 466 | 
            +
                              begin
         | 
| 467 | 
            +
                                entry.value
         | 
| 468 | 
            +
                              rescue DeserializationError
         | 
| 469 | 
            +
                                entry = nil
         | 
| 470 | 
            +
                              end
         | 
| 471 | 
            +
                            end
         | 
| 472 | 
            +
                          end
         | 
| 463 473 | 
             
                          payload[:super_operation] = :fetch if payload
         | 
| 464 474 | 
             
                          payload[:hit] = !!entry if payload
         | 
| 465 475 | 
             
                        end
         | 
| @@ -511,7 +521,12 @@ module ActiveSupport | |
| 511 521 | 
             
                          nil
         | 
| 512 522 | 
             
                        else
         | 
| 513 523 | 
             
                          payload[:hit] = true if payload
         | 
| 514 | 
            -
                           | 
| 524 | 
            +
                          begin
         | 
| 525 | 
            +
                            entry.value
         | 
| 526 | 
            +
                          rescue DeserializationError
         | 
| 527 | 
            +
                            payload[:hit] = false
         | 
| 528 | 
            +
                            nil
         | 
| 529 | 
            +
                          end
         | 
| 515 530 | 
             
                        end
         | 
| 516 531 | 
             
                      else
         | 
| 517 532 | 
             
                        payload[:hit] = false if payload
         | 
| @@ -1038,6 +1053,8 @@ module ActiveSupport | |
| 1038 1053 | 
             
                    end
         | 
| 1039 1054 |  | 
| 1040 1055 | 
             
                    def save_block_result_to_cache(name, options)
         | 
| 1056 | 
            +
                      options = options.dup
         | 
| 1057 | 
            +
             | 
| 1041 1058 | 
             
                      result = instrument(:generate, name, options) do
         | 
| 1042 1059 | 
             
                        yield(name, WriteOptions.new(options))
         | 
| 1043 1060 | 
             
                      end
         | 
| @@ -3,7 +3,7 @@ | |
| 3 3 | 
             
            require "active_support/concern"
         | 
| 4 4 |  | 
| 5 5 | 
             
            class Module
         | 
| 6 | 
            -
              #  | 
| 6 | 
            +
              # == Bite-sized separation of concerns
         | 
| 7 7 | 
             
              #
         | 
| 8 8 | 
             
              # We often find ourselves with a medium-sized chunk of behavior that we'd
         | 
| 9 9 | 
             
              # like to extract, but only mix in to a single class.
         | 
| @@ -18,9 +18,9 @@ class Module | |
| 18 18 | 
             
              # with a comment, as a least-bad alternative. Using modules in separate files
         | 
| 19 19 | 
             
              # means tedious sifting to get a big-picture view.
         | 
| 20 20 | 
             
              #
         | 
| 21 | 
            -
              #  | 
| 21 | 
            +
              # == Dissatisfying ways to separate small concerns
         | 
| 22 22 | 
             
              #
         | 
| 23 | 
            -
              #  | 
| 23 | 
            +
              # === Using comments:
         | 
| 24 24 | 
             
              #
         | 
| 25 25 | 
             
              #   class Todo < ApplicationRecord
         | 
| 26 26 | 
             
              #     # Other todo implementation
         | 
| @@ -37,7 +37,7 @@ class Module | |
| 37 37 | 
             
              #       end
         | 
| 38 38 | 
             
              #   end
         | 
| 39 39 | 
             
              #
         | 
| 40 | 
            -
              #  | 
| 40 | 
            +
              # === With an inline module:
         | 
| 41 41 | 
             
              #
         | 
| 42 42 | 
             
              # Noisy syntax.
         | 
| 43 43 | 
             
              #
         | 
| @@ -61,7 +61,7 @@ class Module | |
| 61 61 | 
             
              #     include EventTracking
         | 
| 62 62 | 
             
              #   end
         | 
| 63 63 | 
             
              #
         | 
| 64 | 
            -
              #  | 
| 64 | 
            +
              # === Mix-in noise exiled to its own file:
         | 
| 65 65 | 
             
              #
         | 
| 66 66 | 
             
              # Once our chunk of behavior starts pushing the scroll-to-understand-it
         | 
| 67 67 | 
             
              # boundary, we give in and move it to a separate file. At this size, the
         | 
| @@ -75,7 +75,7 @@ class Module | |
| 75 75 | 
             
              #     include TodoEventTracking
         | 
| 76 76 | 
             
              #   end
         | 
| 77 77 | 
             
              #
         | 
| 78 | 
            -
              #  | 
| 78 | 
            +
              # == Introducing Module#concerning
         | 
| 79 79 | 
             
              #
         | 
| 80 80 | 
             
              # By quieting the mix-in noise, we arrive at a natural, low-ceremony way to
         | 
| 81 81 | 
             
              # separate bite-sized concerns.
         | 
| @@ -164,7 +164,7 @@ module ActiveSupport | |
| 164 164 | 
             
                #   upcase_first('w')                 # => "W"
         | 
| 165 165 | 
             
                #   upcase_first('')                  # => ""
         | 
| 166 166 | 
             
                def upcase_first(string)
         | 
| 167 | 
            -
                  string.length > 0 ? string[0].upcase.concat(string[1..-1]) : ""
         | 
| 167 | 
            +
                  string.length > 0 ? string[0].upcase.concat(string[1..-1]) : +""
         | 
| 168 168 | 
             
                end
         | 
| 169 169 |  | 
| 170 170 | 
             
                # Converts the first character in the string to lowercase.
         | 
| @@ -173,7 +173,7 @@ module ActiveSupport | |
| 173 173 | 
             
                #   downcase_first('I')                          # => "i"
         | 
| 174 174 | 
             
                #   downcase_first('')                           # => ""
         | 
| 175 175 | 
             
                def downcase_first(string)
         | 
| 176 | 
            -
                  string.length > 0 ? string[0].downcase.concat(string[1..-1]) : ""
         | 
| 176 | 
            +
                  string.length > 0 ? string[0].downcase.concat(string[1..-1]) : +""
         | 
| 177 177 | 
             
                end
         | 
| 178 178 |  | 
| 179 179 | 
             
                # Capitalizes all the words and replaces some characters in the string to
         | 
| @@ -86,6 +86,12 @@ module ActiveSupport | |
| 86 86 | 
             
                mattr_accessor :colorize_logging, default: true
         | 
| 87 87 | 
             
                class_attribute :log_levels, instance_accessor: false, default: {} # :nodoc:
         | 
| 88 88 |  | 
| 89 | 
            +
                LEVEL_CHECKS = {
         | 
| 90 | 
            +
                  debug: -> (logger) { !logger.debug? },
         | 
| 91 | 
            +
                  info: -> (logger) { !logger.info? },
         | 
| 92 | 
            +
                  error: -> (logger) { !logger.error? },
         | 
| 93 | 
            +
                }
         | 
| 94 | 
            +
             | 
| 89 95 | 
             
                class << self
         | 
| 90 96 | 
             
                  def logger
         | 
| 91 97 | 
             
                    @logger ||= if defined?(Rails) && Rails.respond_to?(:logger)
         | 
| @@ -122,7 +128,7 @@ module ActiveSupport | |
| 122 128 | 
             
                    end
         | 
| 123 129 |  | 
| 124 130 | 
             
                    def subscribe_log_level(method, level)
         | 
| 125 | 
            -
                      self.log_levels = log_levels.merge(method =>  | 
| 131 | 
            +
                      self.log_levels = log_levels.merge(method => LEVEL_CHECKS.fetch(level))
         | 
| 126 132 | 
             
                      set_event_levels
         | 
| 127 133 | 
             
                    end
         | 
| 128 134 | 
             
                end
         | 
| @@ -137,7 +143,7 @@ module ActiveSupport | |
| 137 143 | 
             
                end
         | 
| 138 144 |  | 
| 139 145 | 
             
                def silenced?(event)
         | 
| 140 | 
            -
                  logger.nil? ||  | 
| 146 | 
            +
                  logger.nil? || @event_levels[event]&.call(logger)
         | 
| 141 147 | 
             
                end
         | 
| 142 148 |  | 
| 143 149 | 
             
                def call(event)
         | 
| @@ -18,26 +18,30 @@ module ActiveSupport | |
| 18 18 | 
             
                end
         | 
| 19 19 |  | 
| 20 20 | 
             
                module FanoutIteration # :nodoc:
         | 
| 21 | 
            -
                   | 
| 22 | 
            -
                     | 
| 23 | 
            -
             | 
| 24 | 
            -
                    listeners.each do |s|
         | 
| 25 | 
            -
                      yield s
         | 
| 26 | 
            -
                    rescue Exception => e
         | 
| 27 | 
            -
                      exceptions ||= []
         | 
| 28 | 
            -
                      exceptions << e
         | 
| 29 | 
            -
                    end
         | 
| 21 | 
            +
                  private
         | 
| 22 | 
            +
                    def iterate_guarding_exceptions(collection)
         | 
| 23 | 
            +
                      exceptions = nil
         | 
| 30 24 |  | 
| 31 | 
            -
             | 
| 32 | 
            -
             | 
| 33 | 
            -
             | 
| 34 | 
            -
             | 
| 35 | 
            -
                         | 
| 25 | 
            +
                      collection.each do |s|
         | 
| 26 | 
            +
                        yield s
         | 
| 27 | 
            +
                      rescue Exception => e
         | 
| 28 | 
            +
                        exceptions ||= []
         | 
| 29 | 
            +
                        exceptions << e
         | 
| 36 30 | 
             
                      end
         | 
| 37 | 
            -
                    end
         | 
| 38 31 |  | 
| 39 | 
            -
             | 
| 40 | 
            -
             | 
| 32 | 
            +
                      if exceptions
         | 
| 33 | 
            +
                        exceptions = exceptions.flat_map do |exception|
         | 
| 34 | 
            +
                          exception.is_a?(InstrumentationSubscriberError) ? exception.exceptions : [exception]
         | 
| 35 | 
            +
                        end
         | 
| 36 | 
            +
                        if exceptions.size == 1
         | 
| 37 | 
            +
                          raise exceptions.first
         | 
| 38 | 
            +
                        else
         | 
| 39 | 
            +
                          raise InstrumentationSubscriberError.new(exceptions), cause: exceptions.first
         | 
| 40 | 
            +
                        end
         | 
| 41 | 
            +
                      end
         | 
| 42 | 
            +
             | 
| 43 | 
            +
                      collection
         | 
| 44 | 
            +
                    end
         | 
| 41 45 | 
             
                end
         | 
| 42 46 |  | 
| 43 47 | 
             
                # This is a default queue implementation that ships with Notifications.
         | 
| @@ -225,6 +229,8 @@ module ActiveSupport | |
| 225 229 | 
             
                  #     handle.finish
         | 
| 226 230 | 
             
                  #   end
         | 
| 227 231 | 
             
                  class Handle
         | 
| 232 | 
            +
                    include FanoutIteration
         | 
| 233 | 
            +
             | 
| 228 234 | 
             
                    def initialize(notifier, name, id, payload) # :nodoc:
         | 
| 229 235 | 
             
                      @name = name
         | 
| 230 236 | 
             
                      @id = id
         | 
| @@ -239,7 +245,7 @@ module ActiveSupport | |
| 239 245 | 
             
                      ensure_state! :initialized
         | 
| 240 246 | 
             
                      @state = :started
         | 
| 241 247 |  | 
| 242 | 
            -
                      @groups | 
| 248 | 
            +
                      iterate_guarding_exceptions(@groups) do |group|
         | 
| 243 249 | 
             
                        group.start(@name, @id, @payload)
         | 
| 244 250 | 
             
                      end
         | 
| 245 251 | 
             
                    end
         | 
| @@ -252,7 +258,7 @@ module ActiveSupport | |
| 252 258 | 
             
                      ensure_state! :started
         | 
| 253 259 | 
             
                      @state = :finished
         | 
| 254 260 |  | 
| 255 | 
            -
                      @groups | 
| 261 | 
            +
                      iterate_guarding_exceptions(@groups) do |group|
         | 
| 256 262 | 
             
                        group.finish(name, id, payload)
         | 
| 257 263 | 
             
                      end
         | 
| 258 264 | 
             
                    end
         | 
| @@ -43,13 +43,13 @@ module ActiveSupport | |
| 43 43 |  | 
| 44 44 | 
             
                    def exponent
         | 
| 45 45 | 
             
                      max = STORAGE_UNITS.size - 1
         | 
| 46 | 
            -
                      exp = (Math.log(number) / Math.log(base)).to_i
         | 
| 46 | 
            +
                      exp = (Math.log(number.abs) / Math.log(base)).to_i
         | 
| 47 47 | 
             
                      exp = max if exp > max # avoid overflow for the highest unit
         | 
| 48 48 | 
             
                      exp
         | 
| 49 49 | 
             
                    end
         | 
| 50 50 |  | 
| 51 51 | 
             
                    def smaller_than_base?
         | 
| 52 | 
            -
                      number.to_i < base
         | 
| 52 | 
            +
                      number.to_i.abs < base
         | 
| 53 53 | 
             
                    end
         | 
| 54 54 |  | 
| 55 55 | 
             
                    def base
         | 
| @@ -17,6 +17,7 @@ module ActiveSupport | |
| 17 17 | 
             
                SUPPRESSED_WARNINGS = Regexp.union(
         | 
| 18 18 | 
             
                  # TODO: remove if https://github.com/mikel/mail/pull/1557 or similar fix
         | 
| 19 19 | 
             
                  %r{/lib/mail/parsers/.*statement not reached},
         | 
| 20 | 
            +
                  %r{/lib/mail/parsers/.*assigned but unused variable - disp_type_s},
         | 
| 20 21 | 
             
                  %r{/lib/mail/parsers/.*assigned but unused variable - testEof}
         | 
| 21 22 | 
             
                )
         | 
| 22 23 |  | 
    
        metadata
    CHANGED
    
    | @@ -1,14 +1,14 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: activesupport
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 7.1. | 
| 4 | 
            +
              version: 7.1.2
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - David Heinemeier Hansson
         | 
| 8 8 | 
             
            autorequire:
         | 
| 9 9 | 
             
            bindir: bin
         | 
| 10 10 | 
             
            cert_chain: []
         | 
| 11 | 
            -
            date: 2023-10 | 
| 11 | 
            +
            date: 2023-11-10 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies:
         | 
| 13 13 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 14 | 
             
              name: i18n
         | 
| @@ -446,10 +446,10 @@ licenses: | |
| 446 446 | 
             
            - MIT
         | 
| 447 447 | 
             
            metadata:
         | 
| 448 448 | 
             
              bug_tracker_uri: https://github.com/rails/rails/issues
         | 
| 449 | 
            -
              changelog_uri: https://github.com/rails/rails/blob/v7.1. | 
| 450 | 
            -
              documentation_uri: https://api.rubyonrails.org/v7.1. | 
| 449 | 
            +
              changelog_uri: https://github.com/rails/rails/blob/v7.1.2/activesupport/CHANGELOG.md
         | 
| 450 | 
            +
              documentation_uri: https://api.rubyonrails.org/v7.1.2/
         | 
| 451 451 | 
             
              mailing_list_uri: https://discuss.rubyonrails.org/c/rubyonrails-talk
         | 
| 452 | 
            -
              source_code_uri: https://github.com/rails/rails/tree/v7.1. | 
| 452 | 
            +
              source_code_uri: https://github.com/rails/rails/tree/v7.1.2/activesupport
         | 
| 453 453 | 
             
              rubygems_mfa_required: 'true'
         | 
| 454 454 | 
             
            post_install_message:
         | 
| 455 455 | 
             
            rdoc_options:
         |