sorbet-runtime 0.4.4286 → 0.4.4331

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
  SHA1:
3
- metadata.gz: 58fd1f33f4010ee7ed667a320704eee0b40e9d52
4
- data.tar.gz: 957e37e28a0da87dfcff6396623188d571ad1efb
3
+ metadata.gz: 23fe6d1adf71c97852b2e1bd12133d79212b7855
4
+ data.tar.gz: f4ba79a25eb179f3aeba3a0c758876c363a3dc3c
5
5
  SHA512:
6
- metadata.gz: 65b2b394682e14565f1fd12530c128bed0275bf520219e865cedc19c24e03e97dc83931a30649faf3cd1ad4935ca64596e58da8c51b74f9da21287c5b2e1e382
7
- data.tar.gz: 618b4fc7577d7b4fef9b0f97843cc1e8dc47a3408e3904e27280b23219491dba9db8b94bd28e38494d653d93e3bf72223e10e443d4d5530e3ba6553964b5615d
6
+ metadata.gz: cec9cff7dcb4ef500914a038bf009180436bdecb607d6eedbf2c6692a6267360f8b0c48e90b5cd70c0b667761d6ad2db4e8e583bdd40bdb16043bc1122d45e23
7
+ data.tar.gz: b9dda89def4e0ea5e5dd33e4393b93999a8226f788a9080a5ffbd689df880990ec290e01c843fcf7eee336c6ec466984811cb0d32abc21cad03fe2a635bd6880
data/lib/types/boolean.rb CHANGED
@@ -1,4 +1,4 @@
1
- # typed: true
1
+ # typed: strict
2
2
  # frozen_string_literal: true
3
3
 
4
4
  module T
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  # typed: ignore
2
3
 
3
4
  require_relative 'private/methods/_methods'
@@ -2,6 +2,21 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  module T::Configuration
5
+ # Announces to Sorbet that we are currently in a test environment, so it
6
+ # should treat any sigs which are marked `.checked(:tests)` as if they were
7
+ # just a normal sig.
8
+ #
9
+ # If this method is not called, sigs marked `.checked(:tests)` will not be
10
+ # checked. In fact, such methods won't even be wrapped--the runtime will put
11
+ # back the original method.
12
+ #
13
+ # Note: Due to the way sigs are evaluated and methods are wrapped, this
14
+ # method MUST be called before any code calls `sig`. This method raises if
15
+ # it has been called too late.
16
+ def self.enable_checking_for_sigs_marked_checked_tests
17
+ T::Private::RuntimeLevels.enable_checking_in_tests
18
+ end
19
+
5
20
  # Set a handler to handle `TypeError`s raised by any in-line type assertions,
6
21
  # including `T.must`, `T.let`, `T.cast`, and `T.assert_type!`.
7
22
  #
@@ -84,11 +99,10 @@ module T::Configuration
84
99
  # successfully built, but the built sig is incompatible with other sigs in
85
100
  # some way.
86
101
  #
87
- # By default, sig validation errors cause an exception to be raised. One
88
- # exception is for `generated` sigs, for which a message will be logged
89
- # instead of raising. Setting sig_validation_error_handler to an object that
90
- # implements :call (e.g. proc or lambda) allows users to customize the
91
- # behavior when a method signature's build fails.
102
+ # By default, sig validation errors cause an exception to be raised.
103
+ # Setting sig_validation_error_handler to an object that implements :call
104
+ # (e.g. proc or lambda) allows users to customize the behavior when a method
105
+ # signature's build fails.
92
106
  #
93
107
  # @param [Lambda, Proc, Object, nil] value Proc that handles the error (pass
94
108
  # nil to reset to default behavior)
@@ -116,24 +130,7 @@ module T::Configuration
116
130
  end
117
131
 
118
132
  private_class_method def self.sig_validation_error_handler_default(error, opts)
119
- # if this method overrides a generated signature, report that one instead
120
- bad_method = opts[:method]
121
- if !opts[:declaration].generated
122
- super_signature = opts[:super_signature]
123
- raise error if !super_signature&.generated
124
- bad_method = super_signature.method
125
- end
126
-
127
- method_file, method_line = bad_method.source_location
128
- T::Configuration.log_info_handler(
129
- "SIG-DECLARE-FAILED",
130
- {
131
- definition_file: method_file,
132
- definition_line: method_line,
133
- kind: "Delete",
134
- message: error.message,
135
- },
136
- )
133
+ raise error
137
134
  end
138
135
 
139
136
  def self.sig_validation_error_handler(error, opts)
@@ -147,11 +144,9 @@ module T::Configuration
147
144
  # Set a handler for type errors that result from calling a method.
148
145
  #
149
146
  # By default, errors from calling a method cause an exception to be raised.
150
- # One exception is for `generated` sigs, for which a message will be logged
151
- # instead of raising. Setting call_validation_error_handler to an object that
152
- # implements :call (e.g. proc or lambda) allows users to customize the
153
- # behavior when a method is called with invalid parameters, or returns an
154
- # invalid value.
147
+ # Setting call_validation_error_handler to an object that implements :call
148
+ # (e.g. proc or lambda) allows users to customize the behavior when a method
149
+ # is called with invalid parameters, or returns an invalid value.
155
150
  #
156
151
  # @param [Lambda, Proc, Object, nil] value Proc that handles the error
157
152
  # report (pass nil to reset to default behavior)
@@ -182,39 +177,12 @@ module T::Configuration
182
177
  private_class_method def self.call_validation_error_handler_default(signature, opts)
183
178
  method_file, method_line = signature.method.source_location
184
179
  location = opts[:location]
185
- suffix = "Caller: #{location.path}:#{location.lineno}\n" \
186
- "Definition: #{method_file}:#{method_line}"
187
180
 
188
- error_message = "#{opts[:kind]}#{opts[:name] ? " '#{opts[:name]}'" : ''}: #{opts[:message]}\n#{suffix}"
181
+ error_message = "#{opts[:kind]}#{opts[:name] ? " '#{opts[:name]}'" : ''}: #{opts[:message]}\n" \
182
+ "Caller: #{location.path}:#{location.lineno}\n" \
183
+ "Definition: #{method_file}:#{method_line}"
189
184
 
190
- if signature.generated
191
- got = opts[:value].class
192
- got = T.unsafe(T::Enumerable[T.untyped]).describe_obj(opts[:value]) if got < Enumerable
193
- T::Configuration.log_info_handler(
194
- "SIG-CHECK-FAILED",
195
- {
196
- caller_file: location.path,
197
- caller_line: location.lineno,
198
- definition_file: method_file,
199
- definition_line: method_line,
200
- kind: opts[:kind],
201
- name: opts[:name],
202
- expected: opts[:type].name,
203
- got: got,
204
- },
205
- )
206
- elsif signature.soft_notify
207
- T::Configuration.soft_assert_handler(
208
- "TypeError: #{error_message}",
209
- {notify: signature.soft_notify}
210
- )
211
- else
212
- begin
213
- raise TypeError.new(error_message)
214
- rescue TypeError => e # raise into rescue to ensure e.backtrace is populated
215
- T::Private::ErrorHandler.handle_inline_type_error(e)
216
- end
217
- end
185
+ raise TypeError.new(error_message)
218
186
  end
219
187
 
220
188
  def self.call_validation_error_handler(signature, opts)
@@ -18,10 +18,6 @@ module T::Private::Abstract::Declare
18
18
  mod.extend(T::InterfaceWrapper::Helpers)
19
19
 
20
20
  if mod.is_a?(Class)
21
- if mod < T::Struct
22
- raise "#{mod.name} is a subclass of T::Struct and cannot be declared abstract"
23
- end
24
-
25
21
  if type == :interface
26
22
  # Since `interface!` is just `abstract!` with some extra validation, we could technically
27
23
  # allow this, but it's unclear there are good use cases, and it might be confusing.
@@ -306,15 +306,13 @@ module T::Private::Methods
306
306
 
307
307
  if mod.singleton_class?
308
308
  install_singleton_method_added_hook(mod)
309
- install_singleton_method_added_hook(mod.singleton_class)
310
309
  else
311
310
  original_method = T::Private::ClassUtils.replace_method(mod.singleton_class, :method_added) do |name|
312
311
  T::Private::Methods._on_method_added(self, name)
313
312
  original_method.bind(self).call(name)
314
313
  end
315
-
316
- install_singleton_method_added_hook(mod.singleton_class)
317
314
  end
315
+ install_singleton_method_added_hook(mod.singleton_class)
318
316
  end
319
317
 
320
318
  private_class_method def self.install_singleton_method_added_hook(singleton_klass)
@@ -11,7 +11,7 @@ module T::Private::Methods::SignatureValidation
11
11
  # but in practice, you never call them polymorphically. Conceptually, they're standard
12
12
  # methods (this is consistent with how they're treated in other languages, e.g. Java)
13
13
  if signature.mode != Modes.standard
14
- raise "Constructor methods should always be declared using `sig`."
14
+ raise "`initialize` should not use `.abstract` or `.implementation` or any other inheritance modifiers."
15
15
  end
16
16
  return
17
17
  end
@@ -87,7 +87,7 @@ module T::Props
87
87
  # hash. This will not affect objects loaded by {.from_hash}.
88
88
  # @option rules [Proc] :factory A `Proc` that will be called to
89
89
  # generate an initial value for this prop on {#initialize}, if
90
- # none is providede.
90
+ # none is provided.
91
91
  # @option rules [T::Boolean] :immutable If true, this prop cannot be
92
92
  # modified after an instance is created or loaded from a hash.
93
93
  # @option rules [Class,T::Props::CustomType] :array If set, specifies the
@@ -10,7 +10,7 @@ module T::Props::Constructor
10
10
  decorator.props.each do |prop, rules|
11
11
  # It's important to explicitly compare against `true` here; the value can also be :existing or
12
12
  # :on_load (which are truthy) but we don't want to treat those as optional in this context.
13
- if T::Utils::Props.required_prop?(rules) && !decorator.has_default?(rules) && !hash.key?(prop)
13
+ if T::Props::Utils.required_prop?(rules) && !decorator.has_default?(rules) && !hash.key?(prop)
14
14
  raise ArgumentError.new("Missing required prop `#{prop}` for class `#{self.class}`")
15
15
  end
16
16
  end
@@ -149,7 +149,7 @@ class T::Props::Decorator
149
149
  # T::Props::CustomType is not a real object based class so that we can not run real type check call.
150
150
  # T::Props::CustomType.valid?() is only a helper function call.
151
151
  valid =
152
- if type.is_a?(T::Props::CustomType) && T::Utils::Props.optional_prop?(rules)
152
+ if type.is_a?(T::Props::CustomType) && T::Props::Utils.optional_prop?(rules)
153
153
  type.valid?(val)
154
154
  else
155
155
  type_object.valid?(val)
@@ -371,8 +371,8 @@ class T::Props::Decorator
371
371
  if T::Utils::Nilable.is_union_with_nilclass(cls)
372
372
  # :_tnilable is introduced internally for performance purpose so that clients do not need to call
373
373
  # T::Utils::Nilable.is_tnilable(cls) again.
374
- # It is strictly internal: clients should always use T::Utils::Props.required_prop?() or
375
- # T::Utils::Props.optional_prop?() for checking whether a field is required or optional.
374
+ # It is strictly internal: clients should always use T::Props::Utils.required_prop?() or
375
+ # T::Props::Utils.optional_prop?() for checking whether a field is required or optional.
376
376
  rules[:_tnilable] = true
377
377
  end
378
378
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
- # typed: true
2
+ # typed: strict
3
3
 
4
4
  module T::Props
5
5
  class Error < StandardError; end
@@ -31,8 +31,20 @@ module T::Props::Optional::DecoratorMethods
31
31
 
32
32
  def prop_optional?(prop); prop_rules(prop)[:fully_optional]; end
33
33
 
34
- def add_prop_definition(prop, rules)
34
+ def mutate_prop_backdoor!(prop, key, value)
35
+ rules = props.fetch(prop)
36
+ rules = rules.merge(key => value)
37
+ compute_derived_rules(rules)
38
+ @props = props.merge(prop => rules.freeze).freeze
39
+ end
40
+
41
+ def compute_derived_rules(rules)
35
42
  rules[:fully_optional] = !T::Props::Utils.need_nil_write_check?(rules)
43
+ rules[:need_nil_read_check] = T::Props::Utils.need_nil_read_check?(rules)
44
+ end
45
+
46
+ def add_prop_definition(prop, rules)
47
+ compute_derived_rules(rules)
36
48
  super
37
49
  end
38
50
 
@@ -19,13 +19,12 @@ module T::Props::Serializable
19
19
  decorator = self.class.decorator
20
20
  h = {}
21
21
 
22
- decorator.props.keys.each do |prop|
23
- rules = decorator.prop_rules(prop)
22
+ decorator.props.each do |prop, rules|
24
23
  hkey = rules[:serialized_form]
25
24
 
26
- val = decorator.get(self, prop)
25
+ val = decorator.get(self, prop, rules)
27
26
 
28
- if strict && val.nil? && T::Props::Utils.need_nil_write_check?(rules)
27
+ if val.nil? && strict && !rules[:fully_optional]
29
28
  # If the prop was already missing during deserialization, that means the application
30
29
  # code already had to deal with a nil value, which means we wouldn't be accomplishing
31
30
  # much by raising here (other than causing an unnecessary breakage).
@@ -42,40 +41,42 @@ module T::Props::Serializable
42
41
  # Don't serialize values that are nil to save space (both the
43
42
  # nil value itself and the field name in the serialized BSON
44
43
  # document)
45
- next if decorator.prop_dont_store?(prop) || val.nil?
46
-
47
- if rules[:type_is_serializable]
48
- val = val.serialize(strict)
49
- elsif rules[:type_is_array_of_serializable]
50
- if (subtype = rules[:serializable_subtype]).is_a?(T::Props::CustomType)
51
- val = val.map {|el| el && subtype.serialize(el)}
52
- else
53
- val = val.map {|el| el && el.serialize(strict)}
54
- end
55
- elsif rules[:type_is_hash_of_serializable_values] && rules[:type_is_hash_of_custom_type_keys]
56
- key_subtype = rules[:serializable_subtype][:keys]
57
- value_subtype = rules[:serializable_subtype][:values]
58
- if value_subtype.is_a?(T::Props::CustomType)
59
- val = val.each_with_object({}) do |(key, value), result|
60
- result[key_subtype.serialize(key)] = value && value_subtype.serialize(value)
44
+ next if rules[:dont_store] || val.nil?
45
+
46
+ if rules[:serializable_subtype]
47
+ if rules[:type_is_serializable]
48
+ val = val.serialize(strict)
49
+ elsif rules[:type_is_array_of_serializable]
50
+ if (subtype = rules[:serializable_subtype]).is_a?(T::Props::CustomType)
51
+ val = val.map {|el| el && subtype.serialize(el)}
52
+ else
53
+ val = val.map {|el| el && el.serialize(strict)}
61
54
  end
62
- else
55
+ elsif rules[:type_is_hash_of_serializable_values] && rules[:type_is_hash_of_custom_type_keys]
56
+ key_subtype = rules[:serializable_subtype][:keys]
57
+ value_subtype = rules[:serializable_subtype][:values]
58
+ if value_subtype.is_a?(T::Props::CustomType)
59
+ val = val.each_with_object({}) do |(key, value), result|
60
+ result[key_subtype.serialize(key)] = value && value_subtype.serialize(value)
61
+ end
62
+ else
63
+ val = val.each_with_object({}) do |(key, value), result|
64
+ result[key_subtype.serialize(key)] = value && value.serialize(strict)
65
+ end
66
+ end
67
+ elsif rules[:type_is_hash_of_serializable_values]
68
+ value_subtype = rules[:serializable_subtype]
69
+ if value_subtype.is_a?(T::Props::CustomType)
70
+ val = val.transform_values {|v| v && value_subtype.serialize(v)}
71
+ else
72
+ val = val.transform_values {|v| v && v.serialize(strict)}
73
+ end
74
+ elsif rules[:type_is_hash_of_custom_type_keys]
75
+ key_subtype = rules[:serializable_subtype]
63
76
  val = val.each_with_object({}) do |(key, value), result|
64
- result[key_subtype.serialize(key)] = value && value.serialize(strict)
77
+ result[key_subtype.serialize(key)] = value
65
78
  end
66
79
  end
67
- elsif rules[:type_is_hash_of_serializable_values]
68
- value_subtype = rules[:serializable_subtype]
69
- if value_subtype.is_a?(T::Props::CustomType)
70
- val = val.transform_values {|v| v && value_subtype.serialize(v)}
71
- else
72
- val = val.transform_values {|v| v && v.serialize(strict)}
73
- end
74
- elsif rules[:type_is_hash_of_custom_type_keys]
75
- key_subtype = rules[:serializable_subtype]
76
- val = val.each_with_object({}) do |(key, value), result|
77
- result[key_subtype.serialize(key)] = value
78
- end
79
80
  elsif rules[:type_is_custom_type]
80
81
  val = rules[:type].serialize(val)
81
82
 
@@ -88,11 +89,19 @@ module T::Props::Serializable
88
89
  end
89
90
  end
90
91
 
91
- h[hkey] = T::Props::Utils.deep_clone_object(val)
92
+ needs_clone = rules[:type_needs_clone]
93
+ if needs_clone
94
+ if needs_clone == :shallow
95
+ val = val.dup
96
+ else
97
+ val = T::Props::Utils.deep_clone_object(val)
98
+ end
99
+ end
100
+
101
+ h[hkey] = val
92
102
  end
93
103
 
94
- extra_props = decorator.extra_props(self)
95
- h.merge!(extra_props) if extra_props
104
+ h.merge!(@_extra_props) if @_extra_props
96
105
 
97
106
  h
98
107
  end
@@ -116,7 +125,7 @@ module T::Props::Serializable
116
125
  hkey = rules[:serialized_form]
117
126
  val = hash[hkey]
118
127
  if val.nil?
119
- if T::Utils::Props.required_prop?(rules)
128
+ if T::Props::Utils.required_prop?(rules)
120
129
  val = decorator.get_default(rules, self.class)
121
130
  if val.nil?
122
131
  msg = "Tried to deserialize a required prop from a nil value. It's "\
@@ -140,7 +149,7 @@ module T::Props::Serializable
140
149
  T::Configuration.hard_assert_handler(msg, storytime: storytime)
141
150
  end
142
151
  end
143
- elsif T::Props::Utils.need_nil_read_check?(rules)
152
+ elsif rules[:need_nil_read_check]
144
153
  self.required_prop_missing_from_deserialize(p)
145
154
  end
146
155
 
@@ -274,7 +283,7 @@ module T::Props::Serializable::DecoratorMethods
274
283
  end
275
284
 
276
285
  def required_props
277
- @class.props.select {|_, v| T::Utils::Props.required_prop?(v)}.keys
286
+ @class.props.select {|_, v| T::Props::Utils.required_prop?(v)}.keys
278
287
  end
279
288
 
280
289
  def prop_dont_store?(prop); prop_rules(prop)[:dont_store]; end
@@ -44,6 +44,20 @@ module T::Props::Utils
44
44
 
45
45
  # The prop_rules indicate whether we should check for writing a nil value for the prop/field.
46
46
  def self.need_nil_write_check?(prop_rules)
47
- need_nil_read_check?(prop_rules) || T::Utils::Props.required_prop?(prop_rules)
47
+ need_nil_read_check?(prop_rules) || T::Props::Utils.required_prop?(prop_rules)
48
+ end
49
+
50
+ def self.required_prop?(prop_rules)
51
+ # Clients should never reference :_tnilable as the implementation can change.
52
+ !prop_rules[:_tnilable]
53
+ end
54
+
55
+ def self.optional_prop?(prop_rules)
56
+ # Clients should never reference :_tnilable as the implementation can change.
57
+ !!prop_rules[:_tnilable]
58
+ end
59
+
60
+ def self.merge_serialized_optional_rule(prop_rules)
61
+ {'_tnilable' => true}.merge(prop_rules.merge('_tnilable' => true))
48
62
  end
49
63
  end
@@ -1,4 +1,4 @@
1
- # typed: true
1
+ # typed: strict
2
2
  # frozen_string_literal: true
3
3
 
4
4
  #
data/lib/types/sig.rb CHANGED
@@ -1,6 +1,5 @@
1
1
  # frozen_string_literal: true
2
- # typed: true
3
- # rubocop:disable PrisonGuard/NoTopLevelDeclarations, PrisonGuard/PackageMatchesDirectory
2
+ # typed: strict
4
3
 
5
4
  # Used as a mixin to any class so that you can call `sig`.
6
5
  # Docs at https://sorbet.org/docs/sigs
@@ -12,7 +11,7 @@ module T::Sig
12
11
 
13
12
  # At runtime, does nothing, but statically it is treated exactly the same
14
13
  # as T::Sig#sig. Only use it in cases where you can't use T::Sig#sig.
15
- T::Sig::WithoutRuntime.sig {params(blk: T.proc.bind(T::Private::Methods::DeclBuilder).void).void} # rubocop:disable PrisonGuard/PrivateModule
14
+ T::Sig::WithoutRuntime.sig {params(blk: T.proc.bind(T::Private::Methods::DeclBuilder).void).void}
16
15
  def self.sig(&blk); end # rubocop:disable PrisonGuard/BanBuiltinMethodOverride, Lint/DuplicateMethods
17
16
  end
18
17
 
@@ -24,5 +23,3 @@ module T::Sig
24
23
  T::Private::Methods.declare_sig(self, &blk)
25
24
  end
26
25
  end
27
-
28
- # rubocop:enable PrisonGuard/NoTopLevelDeclarations, PrisonGuard/PackageMatchesDirectory
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
- # typed: true
2
+ # typed: strict
3
3
 
4
4
  module T::Types
5
5
  class TypeMember < TypeVariable
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
- # typed: true
2
+ # typed: strict
3
3
 
4
4
  module T::Types
5
5
  class TypeTemplate < TypeVariable
data/lib/types/utils.rb CHANGED
@@ -110,10 +110,6 @@ module T::Utils
110
110
  end
111
111
  end
112
112
 
113
- def self.DANGER_enable_checking_in_tests
114
- T::Private::RuntimeLevels.enable_checking_in_tests
115
- end
116
-
117
113
  # Returns the arity of a method, unwrapping the sig if needed
118
114
  def self.arity(method)
119
115
  arity = method.arity # rubocop:disable PrisonGuard/NoArity
@@ -158,22 +154,6 @@ module T::Utils
158
154
  "#{start_part}#{ellipsis}#{end_part}"
159
155
  end
160
156
 
161
- module Props
162
- def self.required_prop?(prop_rules)
163
- # Clients should never reference :_tnilable as the implementation can change.
164
- !prop_rules[:_tnilable]
165
- end
166
-
167
- def self.optional_prop?(prop_rules)
168
- # Clients should never reference :_tnilable as the implementation can change.
169
- !!prop_rules[:_tnilable]
170
- end
171
-
172
- def self.merge_serialized_optional_rule(prop_rules)
173
- {'_tnilable' => true}.merge(prop_rules.merge('_tnilable' => true))
174
- end
175
- end
176
-
177
157
  module Nilable
178
158
  # :is_union_type, T::Boolean: whether the type is an T::Types::Union type
179
159
  # :non_nilable_type, Class: if it is an T.nilable type, the corresponding underlying type; otherwise, nil.
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.4.4286
4
+ version: 0.4.4331
5
5
  platform: ruby
6
6
  authors:
7
7
  - Stripe
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-06-21 00:00:00.000000000 Z
11
+ date: 2019-06-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: minitest