sorbet-runtime 0.5.5651 → 0.5.5676
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/types/compatibility_patches.rb +22 -8
- data/lib/types/props/decorator.rb +11 -65
- data/lib/types/props/optional.rb +0 -16
- data/lib/types/props/private/serde_transform.rb +34 -7
- data/lib/types/props/type_validation.rb +9 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: baa75d2b35b1bf7be0cbf722cb142f6ef3084cfc4cef71930d1f347fd12ef7d8
|
4
|
+
data.tar.gz: 620be4e8cb01307b5e25d73db2744d989c98efd5f47a9bba078eb13df45dc622
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7f5ac551c51e9a29e970860007e9e9d994e602810202a453005210ff78fdc6f800e37aa6bc52496718e88fed140bad4dddf33e44a8d4ec8ea51a2b6e87b6be1b
|
7
|
+
data.tar.gz: cbb25f6f9e0f0d13fb6e2a7ff97618fdc13d7ac689070af079a5e1078d3ea5c0f6efe77b5d312c1fa424b514acda3bafda69a818a5342a930b42f039f51b1bb9
|
@@ -4,7 +4,8 @@
|
|
4
4
|
require_relative 'private/methods/_methods'
|
5
5
|
|
6
6
|
# Work around an interaction bug with sorbet-runtime and rspec-mocks,
|
7
|
-
# which occurs when using *_any_instance_of
|
7
|
+
# which occurs when using message expectations (*_any_instance_of,
|
8
|
+
# expect, allow) and and_call_original.
|
8
9
|
#
|
9
10
|
# When a sig is defined, sorbet-runtime will replace the sigged method
|
10
11
|
# with a wrapper that, upon first invocation, re-wraps the method with a faster
|
@@ -22,17 +23,30 @@ require_relative 'private/methods/_methods'
|
|
22
23
|
#
|
23
24
|
# We work around this by forcing re-wrapping before rspec stores a reference
|
24
25
|
# to the method.
|
25
|
-
if defined? ::RSpec::Mocks
|
26
|
+
if defined? ::RSpec::Mocks
|
26
27
|
module T
|
27
28
|
module CompatibilityPatches
|
28
|
-
module
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
29
|
+
module RSpecCompatibility
|
30
|
+
module RecorderExtensions
|
31
|
+
def observe!(method_name)
|
32
|
+
method = @klass.instance_method(method_name.to_sym)
|
33
|
+
T::Private::Methods.maybe_run_sig_block_for_method(method)
|
34
|
+
super(method_name)
|
35
|
+
end
|
33
36
|
end
|
37
|
+
::RSpec::Mocks::AnyInstance::Recorder.prepend(RecorderExtensions) if defined?(::RSpec::Mocks::AnyInstance::Recorder)
|
38
|
+
|
39
|
+
module MethodDoubleExtensions
|
40
|
+
def initialize(object, method_name, proxy)
|
41
|
+
if ::Kernel.instance_method(:respond_to?).bind(object).call(method_name, true)
|
42
|
+
method = ::RSpec::Support.method_handle_for(object, method_name)
|
43
|
+
T::Private::Methods.maybe_run_sig_block_for_method(method)
|
44
|
+
end
|
45
|
+
super(object, method_name, proxy)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
::RSpec::Mocks::MethodDouble.prepend(MethodDoubleExtensions) if defined?(::RSpec::Mocks::MethodDouble)
|
34
49
|
end
|
35
|
-
::RSpec::Mocks::AnyInstance::Recorder.prepend(RecorderExtensions)
|
36
50
|
end
|
37
51
|
end
|
38
52
|
end
|
@@ -66,7 +66,6 @@ class T::Props::Decorator
|
|
66
66
|
without_accessors
|
67
67
|
clobber_existing_method!
|
68
68
|
extra
|
69
|
-
optional
|
70
69
|
setter_validate
|
71
70
|
_tnilable
|
72
71
|
}.map {|k| [k, true]}.to_h.freeze, T::Hash[Symbol, T::Boolean])
|
@@ -220,12 +219,6 @@ class T::Props::Decorator
|
|
220
219
|
raise ArgumentError.new("At least one invalid prop arg supplied in #{self}: #{rules.keys.inspect}")
|
221
220
|
end
|
222
221
|
|
223
|
-
if (array = rules[:array])
|
224
|
-
unless array.is_a?(Module)
|
225
|
-
raise ArgumentError.new("Bad class as subtype in prop #{@class.name}.#{name}: #{array.inspect}")
|
226
|
-
end
|
227
|
-
end
|
228
|
-
|
229
222
|
if !(rules[:clobber_existing_method!]) && !(rules[:without_accessors])
|
230
223
|
if BANNED_METHOD_NAMES.include?(name.to_sym)
|
231
224
|
raise ArgumentError.new(
|
@@ -295,47 +288,6 @@ class T::Props::Decorator
|
|
295
288
|
end
|
296
289
|
def prop_defined(name, cls, rules={})
|
297
290
|
cls = T::Utils.resolve_alias(cls)
|
298
|
-
if rules[:optional] == true
|
299
|
-
T::Configuration.hard_assert_handler(
|
300
|
-
'Use of `optional: true` is deprecated, please use `T.nilable(...)` instead.',
|
301
|
-
storytime: {
|
302
|
-
name: name,
|
303
|
-
cls_or_args: cls.to_s,
|
304
|
-
args: rules,
|
305
|
-
klass: decorated_class.name,
|
306
|
-
},
|
307
|
-
)
|
308
|
-
elsif rules[:optional] == false
|
309
|
-
T::Configuration.hard_assert_handler(
|
310
|
-
'Use of `optional: :false` is deprecated as it\'s the default value.',
|
311
|
-
storytime: {
|
312
|
-
name: name,
|
313
|
-
cls_or_args: cls.to_s,
|
314
|
-
args: rules,
|
315
|
-
klass: decorated_class.name,
|
316
|
-
},
|
317
|
-
)
|
318
|
-
elsif rules[:optional] == :on_load
|
319
|
-
T::Configuration.hard_assert_handler(
|
320
|
-
'Use of `optional: :on_load` is deprecated. You probably want `T.nilable(...)` with :raise_on_nil_write instead.',
|
321
|
-
storytime: {
|
322
|
-
name: name,
|
323
|
-
cls_or_args: cls.to_s,
|
324
|
-
args: rules,
|
325
|
-
klass: decorated_class.name,
|
326
|
-
},
|
327
|
-
)
|
328
|
-
elsif rules[:optional] == :existing
|
329
|
-
T::Configuration.hard_assert_handler(
|
330
|
-
'Use of `optional: :existing` is not allowed: you should use use T.nilable (http://go/optional)',
|
331
|
-
storytime: {
|
332
|
-
name: name,
|
333
|
-
cls_or_args: cls.to_s,
|
334
|
-
args: rules,
|
335
|
-
klass: decorated_class.name,
|
336
|
-
},
|
337
|
-
)
|
338
|
-
end
|
339
291
|
|
340
292
|
if T::Utils::Nilable.is_union_with_nilclass(cls)
|
341
293
|
# :_tnilable is introduced internally for performance purpose so that clients do not need to call
|
@@ -350,7 +302,7 @@ class T::Props::Decorator
|
|
350
302
|
if !cls.is_a?(Module)
|
351
303
|
cls = convert_type_to_class(cls)
|
352
304
|
end
|
353
|
-
type_object = smart_coerce(type,
|
305
|
+
type_object = smart_coerce(type, enum: rules[:enum])
|
354
306
|
|
355
307
|
prop_validate_definition!(name, cls, rules, type_object)
|
356
308
|
|
@@ -441,27 +393,21 @@ class T::Props::Decorator
|
|
441
393
|
end
|
442
394
|
|
443
395
|
sig do
|
444
|
-
params(type: PropTypeOrClass,
|
396
|
+
params(type: PropTypeOrClass, enum: T.untyped)
|
445
397
|
.returns(T::Types::Base)
|
446
398
|
end
|
447
|
-
private def smart_coerce(type,
|
399
|
+
private def smart_coerce(type, enum:)
|
448
400
|
# Backwards compatibility for pre-T::Types style
|
449
|
-
|
450
|
-
|
451
|
-
|
452
|
-
|
453
|
-
|
454
|
-
|
455
|
-
T
|
456
|
-
end
|
457
|
-
elsif !enum.nil?
|
458
|
-
if T::Utils.unwrap_nilable(type)
|
459
|
-
T.nilable(T.enum(enum))
|
401
|
+
type = T::Utils.coerce(type)
|
402
|
+
if enum.nil?
|
403
|
+
type
|
404
|
+
else
|
405
|
+
nonnil_type = T::Utils.unwrap_nilable(type)
|
406
|
+
if nonnil_type
|
407
|
+
T.nilable(T.all(nonnil_type, T.enum(enum)))
|
460
408
|
else
|
461
|
-
T.enum(enum)
|
409
|
+
T.all(type, T.enum(enum))
|
462
410
|
end
|
463
|
-
else
|
464
|
-
T::Utils.coerce(type)
|
465
411
|
end
|
466
412
|
end
|
467
413
|
|
data/lib/types/props/optional.rb
CHANGED
@@ -14,19 +14,9 @@ end
|
|
14
14
|
module T::Props::Optional::DecoratorMethods
|
15
15
|
extend T::Sig
|
16
16
|
|
17
|
-
# TODO: clean this up. This set of options is confusing, and some of them are not universally
|
18
|
-
# applicable (e.g., :on_load only applies when using T::Serializable).
|
19
|
-
VALID_OPTIONAL_RULES = Set[
|
20
|
-
:existing, # deprecated
|
21
|
-
:on_load,
|
22
|
-
false,
|
23
|
-
true,
|
24
|
-
].freeze
|
25
|
-
|
26
17
|
VALID_RULE_KEYS = {
|
27
18
|
default: true,
|
28
19
|
factory: true,
|
29
|
-
optional: true,
|
30
20
|
}.freeze
|
31
21
|
private_constant :VALID_RULE_KEYS
|
32
22
|
|
@@ -74,12 +64,6 @@ module T::Props::Optional::DecoratorMethods
|
|
74
64
|
def prop_validate_definition!(name, cls, rules, type)
|
75
65
|
result = super
|
76
66
|
|
77
|
-
if (rules_optional = rules[:optional])
|
78
|
-
if !VALID_OPTIONAL_RULES.include?(rules_optional)
|
79
|
-
raise ArgumentError.new(":optional must be one of #{VALID_OPTIONAL_RULES.inspect}")
|
80
|
-
end
|
81
|
-
end
|
82
|
-
|
83
67
|
if rules.key?(:default) && rules.key?(:factory)
|
84
68
|
raise ArgumentError.new("Setting both :default and :factory is invalid. See: go/chalk-docs")
|
85
69
|
end
|
@@ -26,7 +26,7 @@ module T::Props
|
|
26
26
|
|
27
27
|
sig do
|
28
28
|
params(
|
29
|
-
type: T
|
29
|
+
type: T::Types::Base,
|
30
30
|
mode: ModeType,
|
31
31
|
varname: String,
|
32
32
|
)
|
@@ -99,15 +99,42 @@ module T::Props
|
|
99
99
|
"T::Props::Utils.deep_clone_object(#{varname})"
|
100
100
|
end
|
101
101
|
end
|
102
|
+
when T::Types::Intersection
|
103
|
+
dynamic_fallback = "T::Props::Utils.deep_clone_object(#{varname})"
|
104
|
+
|
105
|
+
# Transformations for any members of the intersection type where we
|
106
|
+
# know what we need to do and did not have to fall back to the
|
107
|
+
# dynamic deep clone method.
|
108
|
+
#
|
109
|
+
# NB: This deliberately does include `nil`, which means we know we
|
110
|
+
# don't need to do any transforming.
|
111
|
+
inner_known = type.types
|
112
|
+
.map {|t| generate(t, mode, varname)}
|
113
|
+
.reject {|t| t == dynamic_fallback}
|
114
|
+
.uniq
|
115
|
+
|
116
|
+
if inner_known.size != 1
|
117
|
+
# If there were no cases where we could tell what we need to do,
|
118
|
+
# e.g. if this is `T.all(SomethingWeird, WhoKnows)`, just use the
|
119
|
+
# dynamic fallback.
|
120
|
+
#
|
121
|
+
# If there were multiple cases and they weren't consistent, e.g.
|
122
|
+
# if this is `T.all(String, T::Array[Integer])`, the type is probably
|
123
|
+
# bogus/uninhabited, but use the dynamic fallback because we still
|
124
|
+
# don't have a better option, and this isn't the place to raise that
|
125
|
+
# error.
|
126
|
+
dynamic_fallback
|
127
|
+
else
|
128
|
+
# This is probably something like `T.all(String, SomeMarker)` or
|
129
|
+
# `T.all(SomeEnum, T.enum(SomeEnum::FOO))` and we should treat it
|
130
|
+
# like String or SomeEnum even if we don't know what to do with
|
131
|
+
# the rest of the type.
|
132
|
+
inner_known.first
|
133
|
+
end
|
102
134
|
when T::Types::Enum
|
103
135
|
generate(T::Utils.lift_enum(type), mode, varname)
|
104
136
|
else
|
105
|
-
|
106
|
-
# Sometimes this comes wrapped in a T::Types::Simple and sometimes not
|
107
|
-
handle_custom_type(varname, T.unsafe(type), mode)
|
108
|
-
else
|
109
|
-
"T::Props::Utils.deep_clone_object(#{varname})"
|
110
|
-
end
|
137
|
+
"T::Props::Utils.deep_clone_object(#{varname})"
|
111
138
|
end
|
112
139
|
end
|
113
140
|
|
@@ -63,7 +63,16 @@ module T::Props::TypeValidation
|
|
63
63
|
when T::Types::FixedHash
|
64
64
|
type.types.values.map {|subtype| find_invalid_subtype(subtype)}.compact.first
|
65
65
|
when T::Types::Union, T::Types::FixedArray
|
66
|
+
# `T.any` is valid if all of the members are valid
|
66
67
|
type.types.map {|subtype| find_invalid_subtype(subtype)}.compact.first
|
68
|
+
when T::Types::Intersection
|
69
|
+
# `T.all` is valid if at least one of the members is valid
|
70
|
+
invalid = type.types.map {|subtype| find_invalid_subtype(subtype)}.compact
|
71
|
+
if invalid.length == type.types.length
|
72
|
+
invalid.first
|
73
|
+
else
|
74
|
+
nil
|
75
|
+
end
|
67
76
|
when T::Types::Enum, T::Types::ClassOf
|
68
77
|
nil
|
69
78
|
when T::Private::Types::TypeAlias
|
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.5.
|
4
|
+
version: 0.5.5676
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Stripe
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-05-
|
11
|
+
date: 2020-05-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: minitest
|