activesupport 7.1.2 → 7.1.3.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6db71966858e675d32617069b0df8dc17b1c5dfe8123c87ae96a28fdb6e2f5e6
4
- data.tar.gz: 81ffe410567130147cd0c6f74943d40404a4031b2cf30f12bfaa2ee698cd5a57
3
+ metadata.gz: 63e4b9598ffeea57d9aa5ab27deb5249cc21324883d53ad536bb02fd5d8e4526
4
+ data.tar.gz: 82041b4d7a4b287404280f004cc9a255ad55ec975682ceb4829be789bce352bb
5
5
  SHA512:
6
- metadata.gz: 99a9131ff9f97e739719621df9ba0a33d3b2fad9b1315397382235f29d33ee130f701d0c0ed767eacf01ccb31607eb26d7f5bb95f37ad86ac57f18817cd9b253
7
- data.tar.gz: ffa6a0ffe90b88c87f65d85ddb32390d20f8c34ab2517f797c34d325839cbf434a0202650cdd54f118bee9a299cf478f83af4222c313f2746e267bbd19003914
6
+ metadata.gz: b0e517fefe56838a7851ec1832ea1cb9fbc10aa392da9f3840ee7d71b0768d29825e03176b5358a5e098ed42686d0602bd13ebb08a750e6294992fb3ac845555
7
+ data.tar.gz: d58c4664ef7962fab547b4d5dc91e7cca0ac647b0b4e080c49129c06ca9d0604dc7d4ee2f9e0347a1100d435789923aafb94adfa49c6cb7f031e18b1e44d798f
data/CHANGELOG.md CHANGED
@@ -1,3 +1,60 @@
1
+ ## Rails 7.1.3.4 (June 04, 2024) ##
2
+
3
+ * No changes.
4
+
5
+
6
+ ## Rails 7.1.3.3 (May 16, 2024) ##
7
+
8
+ * No changes.
9
+
10
+
11
+ ## Rails 7.1.3.2 (February 21, 2024) ##
12
+
13
+ * No changes.
14
+
15
+
16
+ ## Rails 7.1.3.1 (February 21, 2024) ##
17
+
18
+ * No changes.
19
+
20
+
21
+ ## Rails 7.1.3 (January 16, 2024) ##
22
+
23
+ * Handle nil `backtrace_locations` in `ActiveSupport::SyntaxErrorProxy`.
24
+
25
+ *Eugene Kenny*
26
+
27
+ * Fix `ActiveSupport::JSON.encode` to prevent duplicate keys.
28
+
29
+ If the same key exist in both String and Symbol form it could
30
+ lead to the same key being emitted twice.
31
+
32
+ *Manish Sharma*
33
+
34
+ * Fix `ActiveSupport::Cache::Store#read_multi` when using a cache namespace
35
+ and local cache strategy.
36
+
37
+ *Mark Oleson*
38
+
39
+ * Fix `Time.now/DateTime.now/Date.today` to return results in a system timezone after `#travel_to`.
40
+
41
+ There is a bug in the current implementation of #travel_to:
42
+ it remembers a timezone of its argument, and all stubbed methods start
43
+ returning results in that remembered timezone. However, the expected
44
+ behaviour is to return results in a system timezone.
45
+
46
+ *Aleksei Chernenkov*
47
+
48
+ * Fix `:unless_exist` option for `MemoryStore#write` (et al) when using a
49
+ cache namespace.
50
+
51
+ *S. Brent Faulkner*
52
+
53
+ * Fix ActiveSupport::Deprecation to handle blaming generated code.
54
+
55
+ *Jean Boussier*, *fatkodima*
56
+
57
+
1
58
  ## Rails 7.1.2 (November 10, 2023) ##
2
59
 
3
60
  * Fix `:expires_in` option for `RedisCacheStore#write_multi`.
@@ -24,11 +24,11 @@ module ActiveSupport
24
24
  #
25
25
  # Special features:
26
26
  # - Clustering and load balancing. One can specify multiple memcached servers,
27
- # and MemCacheStore will load balance between all available servers. If a
28
- # server goes down, then MemCacheStore will ignore it until it comes back up.
27
+ # and +MemCacheStore+ will load balance between all available servers. If a
28
+ # server goes down, then +MemCacheStore+ will ignore it until it comes back up.
29
29
  #
30
- # MemCacheStore implements the Strategy::LocalCache strategy which implements
31
- # an in-memory cache inside of a block.
30
+ # +MemCacheStore+ implements the Strategy::LocalCache strategy which
31
+ # implements an in-memory cache inside of a block.
32
32
  class MemCacheStore < Store
33
33
  # These options represent behavior overridden by this implementation and should
34
34
  # not be allowed to get down to the Dalli client
@@ -106,14 +106,14 @@ module ActiveSupport
106
106
  end
107
107
  end
108
108
 
109
- # Creates a new MemCacheStore object, with the given memcached server
109
+ # Creates a new +MemCacheStore+ object, with the given memcached server
110
110
  # addresses. Each address is either a host name, or a host-with-port string
111
111
  # in the form of "host_name:port". For example:
112
112
  #
113
113
  # ActiveSupport::Cache::MemCacheStore.new("localhost", "server-downstairs.localnetwork:8229")
114
114
  #
115
115
  # If no addresses are provided, but <tt>ENV['MEMCACHE_SERVERS']</tt> is defined, it will be used instead. Otherwise,
116
- # MemCacheStore will connect to localhost:11211 (the default memcached port).
116
+ # +MemCacheStore+ will connect to localhost:11211 (the default memcached port).
117
117
  # Passing a +Dalli::Client+ instance is deprecated and will be removed. Please pass an address instead.
118
118
  def initialize(*addresses)
119
119
  addresses = addresses.flatten
@@ -18,13 +18,13 @@ module ActiveSupport
18
18
  # a cleanup will occur which tries to prune the cache down to three quarters
19
19
  # of the maximum size by removing the least recently used entries.
20
20
  #
21
- # Unlike other Cache store implementations, MemoryStore does not compress
22
- # values by default. MemoryStore does not benefit from compression as much
21
+ # Unlike other Cache store implementations, +MemoryStore+ does not compress
22
+ # values by default. +MemoryStore+ does not benefit from compression as much
23
23
  # as other Store implementations, as it does not send data over a network.
24
24
  # However, when compression is enabled, it still pays the full cost of
25
25
  # compression in terms of cpu use.
26
26
  #
27
- # MemoryStore is thread-safe.
27
+ # +MemoryStore+ is thread-safe.
28
28
  class MemoryStore < Store
29
29
  module DupCoder # :nodoc:
30
30
  extend self
@@ -209,7 +209,7 @@ module ActiveSupport
209
209
  def write_entry(key, entry, **options)
210
210
  payload = serialize_entry(entry, **options)
211
211
  synchronize do
212
- return false if options[:unless_exist] && exist?(key)
212
+ return false if options[:unless_exist] && exist?(key, namespace: nil)
213
213
 
214
214
  old_payload = @data[key]
215
215
  if old_payload
@@ -19,22 +19,23 @@ module ActiveSupport
19
19
  module Cache
20
20
  # = Redis \Cache \Store
21
21
  #
22
- # Deployment note: Take care to use a *dedicated Redis cache* rather
23
- # than pointing this at your existing Redis server. It won't cope well
24
- # with mixed usage patterns and it won't expire cache entries by default.
22
+ # Deployment note: Take care to use a <b>dedicated Redis cache</b> rather
23
+ # than pointing this at a persistent Redis server (for example, one used as
24
+ # an Active Job queue). Redis won't cope well with mixed usage patterns and it
25
+ # won't expire cache entries by default.
25
26
  #
26
27
  # Redis cache server setup guide: https://redis.io/topics/lru-cache
27
28
  #
28
- # * Supports vanilla Redis, hiredis, and Redis::Distributed.
29
- # * Supports Memcached-like sharding across Redises with Redis::Distributed.
29
+ # * Supports vanilla Redis, hiredis, and +Redis::Distributed+.
30
+ # * Supports Memcached-like sharding across Redises with +Redis::Distributed+.
30
31
  # * Fault tolerant. If the Redis server is unavailable, no exceptions are
31
32
  # raised. Cache fetches are all misses and writes are dropped.
32
33
  # * Local cache. Hot in-memory primary cache within block/middleware scope.
33
- # * +read_multi+ and +write_multi+ support for Redis mget/mset. Use Redis::Distributed
34
- # 4.0.1+ for distributed mget support.
34
+ # * +read_multi+ and +write_multi+ support for Redis mget/mset. Use
35
+ # +Redis::Distributed+ 4.0.1+ for distributed mget support.
35
36
  # * +delete_matched+ support for Redis KEYS globs.
36
37
  class RedisCacheStore < Store
37
- # Keys are truncated with the ActiveSupport digest if they exceed 1kB
38
+ # Keys are truncated with the Active Support digest if they exceed 1kB
38
39
  MAX_KEY_BYTESIZE = 1024
39
40
 
40
41
  DEFAULT_REDIS_OPTIONS = {
@@ -110,8 +111,11 @@ module ActiveSupport
110
111
 
111
112
  # Creates a new Redis cache store.
112
113
  #
113
- # Handles four options: :redis block, :redis instance, single :url
114
- # string, and multiple :url strings.
114
+ # There are four ways to provide the Redis client used by the cache: the
115
+ # +:redis+ param can be a Redis instance or a block that returns a Redis
116
+ # instance, or the +:url+ param can be a string or an array of strings
117
+ # which will be used to create a Redis instance or a +Redis::Distributed+
118
+ # instance.
115
119
  #
116
120
  # Option Class Result
117
121
  # :redis Proc -> options[:redis].call
@@ -134,7 +138,7 @@ module ActiveSupport
134
138
  #
135
139
  # Race condition TTL is not set by default. This can be used to avoid
136
140
  # "thundering herd" cache writes when hot cache entries are expired.
137
- # See <tt>ActiveSupport::Cache::Store#fetch</tt> for more.
141
+ # See ActiveSupport::Cache::Store#fetch for more.
138
142
  #
139
143
  # Setting <tt>skip_nil: true</tt> will not cache nil results:
140
144
  #
@@ -242,7 +246,7 @@ module ActiveSupport
242
246
  # Decrement a cached integer value using the Redis decrby atomic operator.
243
247
  # Returns the updated value.
244
248
  #
245
- # If the key is unset or has expired, it will be set to -amount:
249
+ # If the key is unset or has expired, it will be set to +-amount+:
246
250
  #
247
251
  # cache.decrement("foo") # => -1
248
252
  #
@@ -131,17 +131,20 @@ module ActiveSupport
131
131
  end
132
132
  end
133
133
 
134
- def read_multi_entries(keys, **options)
134
+ def read_multi_entries(names, **options)
135
135
  return super unless local_cache
136
136
 
137
- local_entries = local_cache.read_multi_entries(keys)
137
+ keys_to_names = names.index_by { |name| normalize_key(name, options) }
138
+
139
+ local_entries = local_cache.read_multi_entries(keys_to_names.keys)
140
+ local_entries.transform_keys! { |key| keys_to_names[key] }
138
141
  local_entries.transform_values! do |payload|
139
- deserialize_entry(payload)&.value
142
+ deserialize_entry(payload, **options)&.value
140
143
  end
141
- missed_keys = keys - local_entries.keys
144
+ missed_names = names - local_entries.keys
142
145
 
143
- if missed_keys.any?
144
- local_entries.merge!(super(missed_keys, **options))
146
+ if missed_names.any?
147
+ local_entries.merge!(super(missed_names, **options))
145
148
  else
146
149
  local_entries
147
150
  end
@@ -160,8 +160,8 @@ module ActiveSupport
160
160
  # Some implementations may not support all methods beyond the basic cache
161
161
  # methods of #fetch, #write, #read, #exist?, and #delete.
162
162
  #
163
- # ActiveSupport::Cache::Store can store any Ruby object that is supported by
164
- # its +coder+'s +dump+ and +load+ methods.
163
+ # +ActiveSupport::Cache::Store+ can store any Ruby object that is supported
164
+ # by its +coder+'s +dump+ and +load+ methods.
165
165
  #
166
166
  # cache = ActiveSupport::Cache::MemoryStore.new
167
167
  #
@@ -370,8 +370,8 @@ module ActiveSupport
370
370
  #
371
371
  # ==== Options
372
372
  #
373
- # Internally, +fetch+ calls #read_entry, and calls #write_entry on a cache
374
- # miss. Thus, +fetch+ supports the same options as #read and #write.
373
+ # Internally, +fetch+ calls +read_entry+, and calls +write_entry+ on a
374
+ # cache miss. Thus, +fetch+ supports the same options as #read and #write.
375
375
  # Additionally, +fetch+ supports the following options:
376
376
  #
377
377
  # * <tt>force: true</tt> - Forces a cache "miss," meaning we treat the
@@ -818,7 +818,7 @@ module ActiveSupport
818
818
  end
819
819
  end
820
820
 
821
- def deserialize_entry(payload)
821
+ def deserialize_entry(payload, **)
822
822
  payload.nil? ? nil : @coder.load(payload)
823
823
  rescue DeserializationError
824
824
  nil
@@ -1064,6 +1064,10 @@ module ActiveSupport
1064
1064
  end
1065
1065
  end
1066
1066
 
1067
+ # Enables the dynamic configuration of Cache entry options while ensuring
1068
+ # that conflicting options are not both set. When a block is given to
1069
+ # ActiveSupport::Cache::Store#fetch, the second argument will be an
1070
+ # instance of +WriteOptions+.
1067
1071
  class WriteOptions
1068
1072
  def initialize(options) # :nodoc:
1069
1073
  @options = options
@@ -1081,6 +1085,9 @@ module ActiveSupport
1081
1085
  @options[:expires_in]
1082
1086
  end
1083
1087
 
1088
+ # Sets the Cache entry's +expires_in+ value. If an +expires_at+ option was
1089
+ # previously set, this will unset it since +expires_in+ and +expires_at+
1090
+ # cannot both be set.
1084
1091
  def expires_in=(expires_in)
1085
1092
  @options.delete(:expires_at)
1086
1093
  @options[:expires_in] = expires_in
@@ -1090,6 +1097,9 @@ module ActiveSupport
1090
1097
  @options[:expires_at]
1091
1098
  end
1092
1099
 
1100
+ # Sets the Cache entry's +expires_at+ value. If an +expires_in+ option was
1101
+ # previously set, this will unset it since +expires_at+ and +expires_in+
1102
+ # cannot both be set.
1093
1103
  def expires_at=(expires_at)
1094
1104
  @options.delete(:expires_in)
1095
1105
  @options[:expires_at] = expires_at
@@ -68,7 +68,7 @@ class Object
68
68
  # You can access these methods using the class name instead:
69
69
  #
70
70
  # class Phone < ActiveRecord::Base
71
- # enum phone_number_type: { home: 0, office: 1, mobile: 2 }
71
+ # enum :phone_number_type, { home: 0, office: 1, mobile: 2 }
72
72
  #
73
73
  # with_options presence: true do
74
74
  # validates :phone_number_type, inclusion: { in: Phone.phone_number_types.keys }
@@ -24,7 +24,7 @@ class String
24
24
  #
25
25
  # The second argument, +indent_string+, specifies which indent string to
26
26
  # use. The default is +nil+, which tells the method to make a guess by
27
- # peeking at the first indented line, and fallback to a space if there is
27
+ # peeking at the first indented line, and fall back to a space if there is
28
28
  # none.
29
29
  #
30
30
  # " foo".indent(2) # => " foo"
@@ -57,15 +57,15 @@ module ActiveSupport
57
57
  # You can create a custom behavior or set any from the +DEFAULT_BEHAVIORS+
58
58
  # constant. Available behaviors are:
59
59
  #
60
- # [+raise+] Raise ActiveSupport::DeprecationException.
61
- # [+stderr+] Log all deprecation warnings to <tt>$stderr</tt>.
62
- # [+log+] Log all deprecation warnings to +Rails.logger+.
63
- # [+notify+] Use ActiveSupport::Notifications to notify +deprecation.rails+.
64
- # [+report+] Use ActiveSupport::ErrorReporter to report deprecations.
65
- # [+silence+] Do nothing. On \Rails, set <tt>config.active_support.report_deprecations = false</tt> to disable all behaviors.
60
+ # [+:raise+] Raise ActiveSupport::DeprecationException.
61
+ # [+:stderr+] Log all deprecation warnings to <tt>$stderr</tt>.
62
+ # [+:log+] Log all deprecation warnings to +Rails.logger+.
63
+ # [+:notify+] Use ActiveSupport::Notifications to notify +deprecation.rails+.
64
+ # [+:report+] Use ActiveSupport::ErrorReporter to report deprecations.
65
+ # [+:silence+] Do nothing. On \Rails, set <tt>config.active_support.report_deprecations = false</tt> to disable all behaviors.
66
66
  #
67
67
  # Setting behaviors only affects deprecations that happen after boot time.
68
- # For more information you can read the documentation of the +behavior=+ method.
68
+ # For more information you can read the documentation of the #behavior= method.
69
69
  module Behavior
70
70
  # Whether to print a backtrace along with the warning.
71
71
  attr_accessor :debug
@@ -85,12 +85,12 @@ module ActiveSupport
85
85
  #
86
86
  # Available behaviors:
87
87
  #
88
- # [+raise+] Raise ActiveSupport::DeprecationException.
89
- # [+stderr+] Log all deprecation warnings to <tt>$stderr</tt>.
90
- # [+log+] Log all deprecation warnings to +Rails.logger+.
91
- # [+notify+] Use ActiveSupport::Notifications to notify +deprecation.rails+.
92
- # [+report+] Use ActiveSupport::ErrorReporter to report deprecations.
93
- # [+silence+] Do nothing.
88
+ # [+:raise+] Raise ActiveSupport::DeprecationException.
89
+ # [+:stderr+] Log all deprecation warnings to <tt>$stderr</tt>.
90
+ # [+:log+] Log all deprecation warnings to +Rails.logger+.
91
+ # [+:notify+] Use ActiveSupport::Notifications to notify +deprecation.rails+.
92
+ # [+:report+] Use ActiveSupport::ErrorReporter to report deprecations.
93
+ # [+:silence+] Do nothing.
94
94
  #
95
95
  # Setting behaviors only affects deprecations that happen after boot time.
96
96
  # Deprecation warnings raised by gems are not affected by this setting
@@ -104,15 +104,17 @@ module ActiveSupport
104
104
  # # custom stuff
105
105
  # }
106
106
  #
107
- # If you are using \Rails, you can set <tt>config.active_support.report_deprecations = false</tt> to disable
108
- # all deprecation behaviors. This is similar to the +silence+ option but more performant.
107
+ # If you are using \Rails, you can set
108
+ # <tt>config.active_support.report_deprecations = false</tt> to disable
109
+ # all deprecation behaviors. This is similar to the +:silence+ option but
110
+ # more performant.
109
111
  def behavior=(behavior)
110
112
  @behavior = Array(behavior).map { |b| DEFAULT_BEHAVIORS[b] || arity_coerce(b) }
111
113
  end
112
114
 
113
115
  # Sets the behavior for disallowed deprecations (those configured by
114
116
  # ActiveSupport::Deprecation#disallowed_warnings=) to the specified
115
- # value. As with +behavior=+, this can be a single value, array, or an
117
+ # value. As with #behavior=, this can be a single value, array, or an
116
118
  # object that responds to +call+.
117
119
  def disallowed_behavior=(behavior)
118
120
  @disallowed_behavior = Array(behavior).map { |b| DEFAULT_BEHAVIORS[b] || arity_coerce(b) }
@@ -142,7 +142,9 @@ module ActiveSupport
142
142
  return _extract_callstack(callstack) if callstack.first.is_a? String
143
143
 
144
144
  offending_line = callstack.find { |frame|
145
- frame.absolute_path && !ignored_callstack(frame.absolute_path)
145
+ # Code generated with `eval` doesn't have an `absolute_path`, e.g. templates.
146
+ path = frame.absolute_path || frame.path
147
+ path && !ignored_callstack?(path)
146
148
  } || callstack.first
147
149
 
148
150
  [offending_line.path, offending_line.lineno, offending_line.label]
@@ -150,7 +152,7 @@ module ActiveSupport
150
152
 
151
153
  def _extract_callstack(callstack)
152
154
  warn "Please pass `caller_locations` to the deprecation API" if $VERBOSE
153
- offending_line = callstack.find { |line| !ignored_callstack(line) } || callstack.first
155
+ offending_line = callstack.find { |line| !ignored_callstack?(line) } || callstack.first
154
156
 
155
157
  if offending_line
156
158
  if md = offending_line.match(/^(.+?):(\d+)(?::in `(.*?)')?/)
@@ -162,9 +164,10 @@ module ActiveSupport
162
164
  end
163
165
 
164
166
  RAILS_GEM_ROOT = File.expand_path("../../../..", __dir__) + "/"
167
+ LIB_DIR = RbConfig::CONFIG["libdir"]
165
168
 
166
- def ignored_callstack(path)
167
- path.start_with?(RAILS_GEM_ROOT) || path.start_with?(RbConfig::CONFIG["rubylibdir"])
169
+ def ignored_callstack?(path)
170
+ path.start_with?(RAILS_GEM_ROOT, LIB_DIR)
168
171
  end
169
172
  end
170
173
  end
@@ -9,8 +9,8 @@ module ActiveSupport
9
9
  module VERSION
10
10
  MAJOR = 7
11
11
  MINOR = 1
12
- TINY = 2
13
- PRE = nil
12
+ TINY = 3
13
+ PRE = "4"
14
14
 
15
15
  STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".")
16
16
  end
@@ -7,8 +7,18 @@ module ActiveSupport
7
7
  def translate(key, **options)
8
8
  if html_safe_translation_key?(key)
9
9
  html_safe_options = html_escape_translation_options(options)
10
- translation = I18n.translate(key, **html_safe_options)
11
- html_safe_translation(translation)
10
+
11
+ exception = false
12
+ exception_handler = ->(*args) do
13
+ exception = true
14
+ I18n.exception_handler.call(*args)
15
+ end
16
+ translation = I18n.translate(key, **html_safe_options, exception_handler: exception_handler)
17
+ if exception
18
+ translation
19
+ else
20
+ html_safe_translation(translation)
21
+ end
12
22
  else
13
23
  I18n.translate(key, **options)
14
24
  end
@@ -76,7 +76,7 @@ module ActiveSupport
76
76
  when Hash
77
77
  result = {}
78
78
  value.each do |k, v|
79
- k = k.to_s unless Symbol === k || String === k
79
+ k = k.to_s unless String === k
80
80
  result[k] = jsonify(v)
81
81
  end
82
82
  result