i18n 1.14.8 → 1.15.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: edf1a48f0dd110066260f4d93cd2af16e73e9f91845a16126794d4c9af5b664c
4
- data.tar.gz: 36a488fcbbaefdabb42e1a6f42af534fa36f640de5674d31a92407d6dfd1835d
3
+ metadata.gz: 765ae65d6898b1a8d8b9766960d44bb1ffd9f97f5455b160cf9e33a94c33803c
4
+ data.tar.gz: ff713e7c2e659e33093223a9e6cb9b95e19ba4a21abb311af4db8fc696185b0e
5
5
  SHA512:
6
- metadata.gz: 82897d5266dfb62379930d6f94346dc0e62c14e619995e3933dc6339d0dd6d06d4b491449d1f4eb43128de995e3d9837624e4132b7b506455e0169dece108b7f
7
- data.tar.gz: 8938b0f8d862e989f7427ccb2299722914bd485af9afff24bf0bda6cd8f438dc750cacd8c85d45292787f2e78438ead7c7533d6c696f5d5b9fc7109535a48ee4
6
+ metadata.gz: c5d16537a7975629cb4337f061e5331e76499edf28dfbebcd44f1c5de63423262a95d9d4821366e7e550419aecd5ff92b15be56b50db4b166568b60e93f02642
7
+ data.tar.gz: 290772af479be2b4e345b4434cff6d50a7cdcece0fcb7e9a382c41568f2fbf52c264966e944d3e04fdf27f6d81d51c103f66464c15e2b6bd42e3d60951abc628
data/README.md CHANGED
@@ -19,7 +19,7 @@ We support Rails versions from 6.0 and up.
19
19
 
20
20
  ### Ruby (without Rails)
21
21
 
22
- We support Ruby versions from 3.0 and up.
22
+ We support Ruby versions from 3.2 and up.
23
23
 
24
24
  If you want to use this library without Rails, you can simply add `i18n` to your `Gemfile`:
25
25
 
@@ -54,6 +54,18 @@ I18n.locale = :de
54
54
  I18n.t(:test) # => "Dies ist ein Test"
55
55
  ```
56
56
 
57
+ ### Fiber-safe config updates
58
+
59
+ `Fiber[]` values are inherited by child fibers.
60
+ To avoid sharing mutable config objects across fibers, prefer creating updated configs and setting them with `set!`:
61
+
62
+ ```ruby
63
+ I18n.config.with(locale: :ja).set!
64
+ ```
65
+
66
+ `set!` stores a frozen config in the current execution context.
67
+ This keeps inherited state safe and lets updates happen by replacing config objects.
68
+
57
69
  ## Features
58
70
 
59
71
  * Translation and localization
@@ -16,13 +16,13 @@ module I18n
16
16
  # Returns the current fallbacks implementation. Defaults to +I18n::Locale::Fallbacks+.
17
17
  def fallbacks
18
18
  @@fallbacks ||= I18n::Locale::Fallbacks.new
19
- Thread.current[:i18n_fallbacks] || @@fallbacks
19
+ Fiber[:i18n_fallbacks] || @@fallbacks
20
20
  end
21
21
 
22
22
  # Sets the current fallbacks implementation. Use this to set a different fallbacks implementation.
23
23
  def fallbacks=(fallbacks)
24
24
  @@fallbacks = fallbacks.is_a?(Array) ? I18n::Locale::Fallbacks.new(fallbacks) : fallbacks
25
- Thread.current[:i18n_fallbacks] = @@fallbacks
25
+ Fiber[:i18n_fallbacks] = @@fallbacks
26
26
  end
27
27
  end
28
28
 
@@ -42,7 +42,7 @@ module I18n
42
42
  locale = locale.to_sym
43
43
  translations[locale] ||= Concurrent::Hash.new
44
44
  data = Utils.deep_symbolize_keys(data) unless options.fetch(:skip_symbolize_keys, false)
45
- Utils.deep_merge!(translations[locale], data)
45
+ MUTEX.synchronize { Utils.deep_merge!(translations[locale], data) }
46
46
  end
47
47
 
48
48
  # Get available locales from the translations hash
@@ -68,7 +68,8 @@ module I18n
68
68
  "ŧ"=>"t", "Ũ"=>"U", "ũ"=>"u", "Ū"=>"U", "ū"=>"u", "Ŭ"=>"U", "ŭ"=>"u",
69
69
  "Ů"=>"U", "ů"=>"u", "Ű"=>"U", "ű"=>"u", "Ų"=>"U", "ų"=>"u", "Ŵ"=>"W",
70
70
  "ŵ"=>"w", "Ŷ"=>"Y", "ŷ"=>"y", "Ÿ"=>"Y", "Ź"=>"Z", "ź"=>"z", "Ż"=>"Z",
71
- "ż"=>"z", "Ž"=>"Z", "ž"=>"z"
71
+ "ż"=>"z", "Ž"=>"Z", "ž"=>"z", "Ǫ"=>"O", "ǫ"=>"o", "Ǭ"=>"O",
72
+ "ǭ"=>"o"
72
73
  }.freeze
73
74
 
74
75
  def initialize(rule = nil)
@@ -80,7 +81,7 @@ module I18n
80
81
  def transliterate(string, replacement = nil)
81
82
  replacement ||= DEFAULT_REPLACEMENT_CHAR
82
83
  string.gsub(/[^\x00-\x7f]/u) do |char|
83
- approximations[char] || replacement
84
+ approximations[char] || (replacement == :none ? char : replacement)
84
85
  end
85
86
  end
86
87
 
data/lib/i18n/config.rb CHANGED
@@ -10,7 +10,41 @@ module I18n
10
10
  defined?(@locale) && @locale != nil ? @locale : default_locale
11
11
  end
12
12
 
13
- # Sets the current locale pseudo-globally, i.e. in the Thread.current hash.
13
+ def initialize
14
+ @owner = Fiber.current
15
+ end
16
+
17
+ def owned_by?(fiber)
18
+ @owner == fiber
19
+ end
20
+
21
+ def owner=(fiber)
22
+ @owner = fiber
23
+ end
24
+
25
+ def initialize_copy(other)
26
+ @owner = Fiber.current
27
+ end
28
+
29
+ # Returns a copied configuration with the provided attributes set.
30
+ def with(**attrs)
31
+ dup.tap do |copy|
32
+ attrs.each do |name, value|
33
+ copy.public_send("#{name}=", value)
34
+ end
35
+ end
36
+ end
37
+
38
+ # Sets this configuration as the current one for the active execution context.
39
+ # The stored configuration is frozen to avoid sharing mutable state between fibers.
40
+ def set!
41
+ self.owner = Fiber.current unless frozen?
42
+ freeze
43
+ I18n.config = self
44
+ self
45
+ end
46
+
47
+ # Sets the current locale pseudo-globally, i.e. in the Thread.current or Fiber local hash.
14
48
  def locale=(locale)
15
49
  I18n.enforce_available_locales!(locale)
16
50
  @locale = locale && locale.to_sym
@@ -10,7 +10,7 @@ module I18n
10
10
  def call(env)
11
11
  @app.call(env)
12
12
  ensure
13
- Thread.current.thread_variable_set(:i18n_config, I18n::Config.new)
13
+ Fiber[:i18n_config] = I18n::Config.new
14
14
  end
15
15
 
16
16
  end
data/lib/i18n/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module I18n
4
- VERSION = "1.14.8"
4
+ VERSION = "1.15.0"
5
5
  end
data/lib/i18n.rb CHANGED
@@ -55,13 +55,29 @@ module I18n
55
55
  module Base
56
56
  # Gets I18n configuration object.
57
57
  def config
58
- Thread.current.thread_variable_get(:i18n_config) ||
59
- Thread.current.thread_variable_set(:i18n_config, I18n::Config.new)
58
+ current = Fiber[:i18n_config] || self.config = I18n::Config.new
59
+ if current.respond_to?(:owned_by?) && !current.owned_by?(Fiber.current)
60
+ current = current.dup
61
+ Fiber[:i18n_config] = current
62
+ end
63
+
64
+ current
65
+ end
66
+
67
+ # Gets a mutable I18n configuration object.
68
+ def writable_config
69
+ current = config
70
+ return current unless current.frozen?
71
+
72
+ current = current.dup
73
+ Fiber[:i18n_config] = current
74
+ current
60
75
  end
61
76
 
62
77
  # Sets I18n configuration object.
63
78
  def config=(value)
64
- Thread.current.thread_variable_set(:i18n_config, value)
79
+ Fiber[:i18n_config] = value
80
+ value.owner = Fiber.current if value.respond_to?(:owner=) && !value.frozen?
65
81
  end
66
82
 
67
83
  # Write methods which delegates to the configuration object
@@ -73,7 +89,7 @@ module I18n
73
89
  end
74
90
 
75
91
  def #{method}=(value)
76
- config.#{method} = (value)
92
+ writable_config.#{method} = (value)
77
93
  end
78
94
  DELEGATORS
79
95
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: i18n
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.14.8
4
+ version: 1.15.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sven Fuchs
@@ -10,10 +10,9 @@ authors:
10
10
  - Stephan Soller
11
11
  - Saimon Moore
12
12
  - Ryan Bigg
13
- autorequire:
14
13
  bindir: bin
15
14
  cert_chain: []
16
- date: 2025-12-21 00:00:00.000000000 Z
15
+ date: 1980-01-02 00:00:00.000000000 Z
17
16
  dependencies:
18
17
  - !ruby/object:Gem::Dependency
19
18
  name: concurrent-ruby
@@ -91,7 +90,6 @@ metadata:
91
90
  changelog_uri: https://github.com/ruby-i18n/i18n/releases
92
91
  documentation_uri: https://guides.rubyonrails.org/i18n.html
93
92
  source_code_uri: https://github.com/ruby-i18n/i18n
94
- post_install_message:
95
93
  rdoc_options: []
96
94
  require_paths:
97
95
  - lib
@@ -99,15 +97,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
99
97
  requirements:
100
98
  - - ">="
101
99
  - !ruby/object:Gem::Version
102
- version: 2.3.0
100
+ version: '3.1'
103
101
  required_rubygems_version: !ruby/object:Gem::Requirement
104
102
  requirements:
105
103
  - - ">="
106
104
  - !ruby/object:Gem::Version
107
105
  version: 1.3.5
108
106
  requirements: []
109
- rubygems_version: 3.5.23
110
- signing_key:
107
+ rubygems_version: 3.6.9
111
108
  specification_version: 4
112
109
  summary: New wave Internationalization support for Ruby
113
110
  test_files: []