sorbet-runtime 0.6.12473 → 0.6.12598

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: f39c8316a030588d8034f9b5af629ad6b9f73b97fc8e743e6cc0dddb3a01d068
4
- data.tar.gz: 98220709558a565d6765b0dd0e8123054c3fca2e1bc4364da0c443d3c76e6f97
3
+ metadata.gz: ebfe10c877dc0338945dbddb20e6f27e2e4570c951fe1a82f170c48e2d04a954
4
+ data.tar.gz: 5f73781d8a144940b29b411882aa9aa715b7e8096b649a7aeec5144d9d828199
5
5
  SHA512:
6
- metadata.gz: 98a4f90009a82357da81795f493edb4784735d8375be770ebb4e55ecdb585ecc9de58fc26cbe56588e57ba3add4db9d3d6c0eaa7f9a4b005f07aab856419199f
7
- data.tar.gz: c49f9d84a3c4fd906319ea0d704bb51799e3e22844c54f1b9c8f73870547fd5f1a815972683bdd2c2969f357ad145f6dec61728746365686ddc0179444104cf3
6
+ metadata.gz: 0cb2d697f780a36b05d24fecebbd931d03ba0947226f9df95e1ea083c69992fc52d1eb0688ad4ee14adadf370e97d3f334ba7c16a77a9aca310de7ff2e2f711a
7
+ data.tar.gz: 6876486f827f3e236a8bc7cf3cf323a1a09048ec9cb912d9b57cf30a0ee5b4d21e81915c4a935861fdd6b2982417e3aec23af602051f01181a481fd3ce1fc53b
@@ -546,16 +546,6 @@ module T::Configuration
546
546
  @legacy_t_enum_migration_mode || false
547
547
  end
548
548
 
549
- @prop_freeze_handler = ->(instance, prop_name) {}
550
-
551
- def self.prop_freeze_handler=(handler)
552
- @prop_freeze_handler = handler
553
- end
554
-
555
- def self.prop_freeze_handler
556
- @prop_freeze_handler
557
- end
558
-
559
549
  @sealed_violation_whitelist = nil
560
550
  # @param [Array] sealed_violation_whitelist An array of Regexp to validate
561
551
  # whether inheriting /including a sealed module outside the defining module
@@ -12,7 +12,7 @@
12
12
  # modules that override the `hash` method with something completely broken.
13
13
  module T::Private::Abstract::Data
14
14
  def self.get(mod, key)
15
- mod.instance_variable_get("@opus_abstract__#{key}") if key?(mod, key)
15
+ mod.instance_variable_get("@opus_abstract__#{key}")
16
16
  end
17
17
 
18
18
  def self.set(mod, key, value)
@@ -277,6 +277,9 @@ module T::Private::Methods::SignatureValidation
277
277
  end
278
278
  end
279
279
 
280
+ ALLOW_INCOMPATIBLE_VISIBILITY = [:visibility, true].freeze
281
+ private_constant :ALLOW_INCOMPATIBLE_VISIBILITY
282
+
280
283
  def self.validate_override_visibility(signature, super_signature)
281
284
  return if super_signature.mode == Modes.untyped
282
285
  # This departs from the behavior of other `validate_override_whatever` functions in that it
@@ -284,8 +287,8 @@ module T::Private::Methods::SignatureValidation
284
287
  # done because the primary method for silencing these errors (`allow_incompatible: :visibility`)
285
288
  # requires an `override` node to attach to. Once we have static override checking for implicitly
286
289
  # overridden methods, we can remove this.
287
- return unless [Modes.override, Modes.overridable_override].include?(signature.mode)
288
- return if [:visibility, true].include?(signature.override_allow_incompatible)
290
+ return unless Modes::OVERRIDE_MODES.include?(signature.mode)
291
+ return if ALLOW_INCOMPATIBLE_VISIBILITY.include?(signature.override_allow_incompatible)
289
292
  method = signature.method
290
293
  super_method = super_signature.method
291
294
  mode_noun = super_signature.mode == Modes.abstract ? 'implementation' : 'override'
@@ -305,8 +308,11 @@ module T::Private::Methods::SignatureValidation
305
308
  end
306
309
 
307
310
  # Higher = more restrictive.
311
+ METHOD_VISIBILITIES = %i[public protected private].freeze
312
+ private_constant :METHOD_VISIBILITIES
313
+
308
314
  private_class_method def self.visibility_strength(vis)
309
- %i[public protected private].find_index(vis)
315
+ METHOD_VISIBILITIES.find_index(vis)
310
316
  end
311
317
 
312
318
  private_class_method def self.base_override_loc_str(signature, super_signature)
@@ -70,7 +70,7 @@ module T::Private::Sealed
70
70
 
71
71
  def self.validate_inheritance(caller_loc, parent, child, verb)
72
72
  this_file = caller_loc&.path
73
- decl_file = parent.instance_variable_get(:@sorbet_sealed_module_decl_file) if sealed_module?(parent)
73
+ decl_file = parent.instance_variable_get(:@sorbet_sealed_module_decl_file)
74
74
 
75
75
  if !this_file
76
76
  raise "Could not use backtrace to determine file for #{verb} child #{child}"
@@ -132,17 +132,14 @@ module T::Props
132
132
  end
133
133
 
134
134
  # Shorthand helper to define a `prop` with `immutable => true`
135
- sig { params(name: Symbol, cls_or_args: T.untyped, args: T.untyped).void }
136
- def const(name, cls_or_args, **args)
137
- if (cls_or_args.is_a?(Hash) && cls_or_args.key?(:immutable)) || args.key?(:immutable)
135
+ sig { params(name: Symbol, cls: T.untyped, rules: T.untyped).void }
136
+ def const(name, cls, **rules)
137
+ if rules.key?(:immutable)
138
138
  Kernel.raise ArgumentError.new("Cannot pass 'immutable' argument when using 'const' keyword to define a prop")
139
139
  end
140
140
 
141
- if cls_or_args.is_a?(Hash)
142
- self.prop(name, **cls_or_args.merge(immutable: true))
143
- else
144
- self.prop(name, cls_or_args, **args.merge(immutable: true))
145
- end
141
+ rules[:immutable] = true
142
+ self.prop(name, cls, **rules)
146
143
  end
147
144
 
148
145
  def included(child)
@@ -174,7 +174,9 @@ class T::Props::Decorator
174
174
  .checked(:never)
175
175
  end
176
176
  def prop_get(instance, prop, rules=prop_rules(prop))
177
- val = instance.instance_variable_get(rules[:accessor_key]) if instance.instance_variable_defined?(rules[:accessor_key])
177
+ # `instance_variable_get` will return nil if the variable doesn't exist
178
+ # which is what we want to have happen for the logic below.
179
+ val = instance.instance_variable_get(rules[:accessor_key])
178
180
  if !val.nil?
179
181
  val
180
182
  elsif (d = rules[:ifunset])
@@ -194,7 +196,9 @@ class T::Props::Decorator
194
196
  .checked(:never)
195
197
  end
196
198
  def prop_get_if_set(instance, prop, rules=prop_rules(prop))
197
- instance.instance_variable_get(rules[:accessor_key]) if instance.instance_variable_defined?(rules[:accessor_key])
199
+ # `instance_variable_get` will return nil if the variable doesn't exist
200
+ # which is what we want to have happen for the return value here.
201
+ instance.instance_variable_get(rules[:accessor_key])
198
202
  end
199
203
  alias_method :get, :prop_get_if_set # Alias for backwards compatibility
200
204
 
@@ -238,7 +242,9 @@ class T::Props::Decorator
238
242
  end
239
243
 
240
244
  if rules.keys.any? { |k| !valid_rule_key?(k) }
241
- raise ArgumentError.new("At least one invalid prop arg supplied in #{self}: #{rules.keys.inspect}")
245
+ invalid_keys = rules.keys.reject { |k| valid_rule_key?(k) }
246
+ suffix = invalid_keys.size == 1 ? "" : "s"
247
+ raise ArgumentError.new("Invalid prop arg#{suffix} supplied in #{self}: #{invalid_keys.inspect}")
242
248
  end
243
249
 
244
250
  if !rules[:clobber_existing_method!] && !rules[:without_accessors] && BANNED_METHOD_NAMES.include?(name.to_sym)
@@ -259,6 +265,8 @@ class T::Props::Decorator
259
265
  end
260
266
 
261
267
  SAFE_NAME = T.let(/\A[A-Za-z_][A-Za-z0-9_-]*\z/.freeze, Regexp, checked: false)
268
+ # Should be exactly the same as `SAFE_NAME`, but with a leading `@`.
269
+ SAFE_ACCESSOR_KEY_NAME = T.let(/\A@[A-Za-z_][A-Za-z0-9_-]*\z/.freeze, Regexp, checked: false)
262
270
 
263
271
  # Used to validate both prop names and serialized forms
264
272
  sig { params(name: T.any(Symbol, String)).void.checked(:never) }
@@ -319,9 +327,9 @@ class T::Props::Decorator
319
327
  sig(:final) { params(name: Symbol).returns(T::Boolean).checked(:never) }
320
328
  private def method_defined_on_ancestor?(name)
321
329
  (@class.method_defined?(name) || @class.private_method_defined?(name)) &&
322
- # Unfortunately, older versions of ruby don't allow the second parameter on
323
- # `private_method_defined?`.
324
- (!@class.method_defined?(name, false) && !@class.private_method_defined?(name, false))
330
+ # Unfortunately, older versions of ruby don't allow the second parameter on
331
+ # `private_method_defined?`.
332
+ (!@class.method_defined?(name, false) && !@class.private_method_defined?(name, false))
325
333
  end
326
334
 
327
335
  sig(:final) { params(name: Symbol, rules: Rules).void.checked(:never) }
@@ -402,8 +410,6 @@ class T::Props::Decorator
402
410
 
403
411
  # extra arbitrary metadata attached by the code defining this property
404
412
 
405
- validate_not_missing_sensitivity(name, rules)
406
-
407
413
  # for backcompat (the `:array` key is deprecated but because the name is
408
414
  # so generic it's really hard to be sure it's not being relied on anymore)
409
415
  if type.is_a?(T::Types::TypedArray)
@@ -479,35 +485,6 @@ class T::Props::Decorator
479
485
  end
480
486
  end
481
487
 
482
- # checked(:never) - Rules hash is expensive to check
483
- sig { params(prop_name: Symbol, rules: Rules).void.checked(:never) }
484
- private def validate_not_missing_sensitivity(prop_name, rules)
485
- if rules[:sensitivity].nil?
486
- if rules[:redaction]
487
- T::Configuration.hard_assert_handler(
488
- "#{@class}##{prop_name} has a 'redaction:' annotation but no " \
489
- "'sensitivity:' annotation. This is probably wrong, because if a " \
490
- "prop needs redaction then it is probably sensitive. Add a " \
491
- "sensitivity annotation like 'sensitivity: Opus::Sensitivity::PII." \
492
- "whatever', or explicitly override this check with 'sensitivity: []'."
493
- )
494
- end
495
- # TODO(PRIVACYENG-982) Ideally we'd also check for 'password' and possibly
496
- # other terms, but this interacts badly with ProtoDefinedDocument because
497
- # the proto syntax currently can't declare "sensitivity: []"
498
- if /\bsecret\b/.match?(prop_name)
499
- T::Configuration.hard_assert_handler(
500
- "#{@class}##{prop_name} has the word 'secret' in its name, but no " \
501
- "'sensitivity:' annotation. This is probably wrong, because if a " \
502
- "prop is named 'secret' then it is probably sensitive. Add a " \
503
- "sensitivity annotation like 'sensitivity: Opus::Sensitivity::NonPII." \
504
- "security_token', or explicitly override this check with " \
505
- "'sensitivity: []'."
506
- )
507
- end
508
- end
509
- end
510
-
511
488
  # Create `#{prop_name}_redacted` method
512
489
  sig do
513
490
  params(
@@ -37,7 +37,7 @@ module T::Props
37
37
 
38
38
  sig { returns(T::Boolean) }
39
39
  def self.lazy_evaluation_enabled?
40
- !defined?(@lazy_evaluation_disabled) || !@lazy_evaluation_disabled
40
+ !@lazy_evaluation_disabled
41
41
  end
42
42
 
43
43
  module DecoratorMethods
@@ -16,6 +16,8 @@ module T::Props
16
16
  module DeserializerGenerator
17
17
  extend T::Sig
18
18
 
19
+ CAN_USE_SYMBOL_NAME = T.let(RUBY_VERSION >= "3.3.0", T::Boolean)
20
+
19
21
  # Generate a method that takes a T::Hash[String, T.untyped] representing
20
22
  # serialized props, sets instance variables for each prop found in the
21
23
  # input, and returns the count of we props set (which we can use to check
@@ -29,19 +31,21 @@ module T::Props
29
31
  .checked(:never)
30
32
  end
31
33
  def self.generate(props, defaults)
32
- stored_props = props.reject { |_, rules| rules[:dont_store] }
33
- parts = stored_props.map do |prop, rules|
34
+ parts = props.filter_map do |prop, rules|
35
+ next if rules[:dont_store]
36
+
34
37
  # All of these strings should already be validated (directly or
35
38
  # indirectly) in `validate_prop_name`, so we don't bother with a nice
36
39
  # error message, but we double check here to prevent a refactoring
37
40
  # from introducing a security vulnerability.
38
- raise unless T::Props::Decorator::SAFE_NAME.match?(prop.to_s)
41
+ raise unless T::Props::Decorator::SAFE_NAME.match?(CAN_USE_SYMBOL_NAME ? prop.name : prop.to_s)
39
42
 
40
43
  hash_key = rules.fetch(:serialized_form)
41
44
  raise unless T::Props::Decorator::SAFE_NAME.match?(hash_key)
42
45
 
43
- ivar_name = rules.fetch(:accessor_key).to_s
44
- raise unless ivar_name.start_with?('@') && T::Props::Decorator::SAFE_NAME.match?(ivar_name[1..-1])
46
+ key = rules.fetch(:accessor_key)
47
+ ivar_name = CAN_USE_SYMBOL_NAME ? key.name : key.to_s
48
+ raise unless ivar_name.start_with?('@') && T::Props::Decorator::SAFE_ACCESSOR_KEY_NAME.match?(ivar_name)
45
49
 
46
50
  transformation = SerdeTransform.generate(
47
51
  T::Utils::Nilable.get_underlying_type_object(rules.fetch(:type_object)),
@@ -90,7 +94,7 @@ module T::Props
90
94
 
91
95
  <<~RUBY
92
96
  def __t_props_generated_deserialize(hash)
93
- found = #{stored_props.size}
97
+ found = #{parts.size}
94
98
  #{parts.join("\n\n")}
95
99
  found
96
100
  end
@@ -16,6 +16,8 @@ module T::Props
16
16
  module SerializerGenerator
17
17
  extend T::Sig
18
18
 
19
+ CAN_USE_SYMBOL_NAME = T.let(RUBY_VERSION >= "3.3.0", T::Boolean)
20
+
19
21
  sig do
20
22
  params(
21
23
  props: T::Hash[Symbol, T::Hash[Symbol, T.untyped]],
@@ -24,19 +26,21 @@ module T::Props
24
26
  .checked(:never)
25
27
  end
26
28
  def self.generate(props)
27
- stored_props = props.reject { |_, rules| rules[:dont_store] }
28
- parts = stored_props.map do |prop, rules|
29
+ parts = props.filter_map do |prop, rules|
30
+ next if rules[:dont_store]
31
+
29
32
  # All of these strings should already be validated (directly or
30
33
  # indirectly) in `validate_prop_name`, so we don't bother with a nice
31
34
  # error message, but we double check here to prevent a refactoring
32
35
  # from introducing a security vulnerability.
33
- raise unless T::Props::Decorator::SAFE_NAME.match?(prop.to_s)
36
+ raise unless T::Props::Decorator::SAFE_NAME.match?(CAN_USE_SYMBOL_NAME ? prop.name : prop.to_s)
34
37
 
35
38
  hash_key = rules.fetch(:serialized_form)
36
39
  raise unless T::Props::Decorator::SAFE_NAME.match?(hash_key)
37
40
 
38
- ivar_name = rules.fetch(:accessor_key).to_s
39
- raise unless ivar_name.start_with?('@') && T::Props::Decorator::SAFE_NAME.match?(ivar_name[1..-1])
41
+ key = rules.fetch(:accessor_key)
42
+ ivar_name = CAN_USE_SYMBOL_NAME ? key.name : key.to_s
43
+ raise unless ivar_name.start_with?('@') && T::Props::Decorator::SAFE_ACCESSOR_KEY_NAME.match?(ivar_name)
40
44
 
41
45
  transformed_val = SerdeTransform.generate(
42
46
  T::Utils::Nilable.get_underlying_type_object(rules.fetch(:type_object)),
@@ -121,8 +121,8 @@ module T::Props::Serializable
121
121
  private def with_existing_hash(changed_props, existing_hash:)
122
122
  serialized = existing_hash
123
123
  new_val = self.class.from_hash(serialized.merge(recursive_stringify_keys(changed_props)))
124
- old_extra = self.instance_variable_get(:@_extra_props) if self.instance_variable_defined?(:@_extra_props)
125
- new_extra = new_val.instance_variable_get(:@_extra_props) if new_val.instance_variable_defined?(:@_extra_props)
124
+ old_extra = self.instance_variable_get(:@_extra_props)
125
+ new_extra = new_val.instance_variable_get(:@_extra_props)
126
126
  if old_extra != new_extra
127
127
  difference =
128
128
  if old_extra
@@ -137,8 +137,7 @@ module T::Props::Serializable
137
137
 
138
138
  # Asserts if this property is missing during strict serialize
139
139
  private def required_prop_missing_from_serialize(prop)
140
- if defined?(@_required_props_missing_from_deserialize) &&
141
- @_required_props_missing_from_deserialize&.include?(prop)
140
+ if @_required_props_missing_from_deserialize&.include?(prop)
142
141
  # If the prop was already missing during deserialization, that means the application
143
142
  # code already had to deal with a nil value, which means we wouldn't be accomplishing
144
143
  # much by raising here (other than causing an unnecessary breakage).
@@ -353,11 +352,7 @@ module T::Props::Serializable::DecoratorMethods
353
352
  private_constant :EMPTY_EXTRA_PROPS
354
353
 
355
354
  def extra_props(instance)
356
- if instance.instance_variable_defined?(:@_extra_props)
357
- instance.instance_variable_get(:@_extra_props) || EMPTY_EXTRA_PROPS
358
- else
359
- EMPTY_EXTRA_PROPS
360
- end
355
+ instance.instance_variable_get(:@_extra_props) || EMPTY_EXTRA_PROPS
361
356
  end
362
357
 
363
358
  # adds to the default result of T::Props::PrettyPrintable
@@ -34,6 +34,8 @@ module T::Types
34
34
  case other
35
35
  when TEnum
36
36
  @val == other.val
37
+ when Simple
38
+ other.raw_type.===(@val)
37
39
  else
38
40
  false
39
41
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sorbet-runtime
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.12473
4
+ version: 0.6.12598
5
5
  platform: ruby
6
6
  authors:
7
7
  - Stripe
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2025-08-30 00:00:00.000000000 Z
11
+ date: 2025-09-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: minitest