sorbet-runtime 0.4.4355 → 0.4.4375
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 +4 -4
- data/lib/types/_types.rb +3 -10
- data/lib/types/configuration.rb +13 -0
- data/lib/types/private/methods/_methods.rb +3 -3
- data/lib/types/private/methods/decl_builder.rb +20 -28
- data/lib/types/private/methods/signature.rb +4 -4
- data/lib/types/private/runtime_levels.rb +15 -0
- data/lib/types/props/decorator.rb +13 -9
- data/lib/types/props/pretty_printable.rb +1 -0
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 62d9529bff7ed508939f3a8afec4dd9b2795190c
|
|
4
|
+
data.tar.gz: 6101b7766ca75e44e1372931b124c9ad505bb4e1
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: c2220c978ad9e510fde8ee0435d12a334b670fbb94178ba3a79217ade6e1b34931596a6d57616445887e951bf0f69ac6e9e9b18096235ce71d8d78da7a2319bc
|
|
7
|
+
data.tar.gz: ef8dd00fea3274ef9b2847c519388a7a2949a619cdae065361bc34fbe74f2343a1207ae6069805f0e08b0d24934102e6d9234f2fda844159310f942d02f09b37
|
data/lib/types/_types.rb
CHANGED
|
@@ -176,20 +176,13 @@ module T
|
|
|
176
176
|
# Intended to be used to promise sorbet that a given nilable value happens
|
|
177
177
|
# to contain a non-nil value at this point.
|
|
178
178
|
#
|
|
179
|
-
# sig {params(arg: T.nilable(A)
|
|
180
|
-
def self.must(arg
|
|
179
|
+
# sig {params(arg: T.nilable(A)).returns(A)}
|
|
180
|
+
def self.must(arg)
|
|
181
181
|
return arg if arg
|
|
182
182
|
return arg if arg == false
|
|
183
183
|
|
|
184
184
|
begin
|
|
185
|
-
|
|
186
|
-
if !T.unsafe(msg).is_a?(String)
|
|
187
|
-
raise TypeError.new("T.must expects a string as second argument")
|
|
188
|
-
end
|
|
189
|
-
else
|
|
190
|
-
msg = "Passed `nil` into T.must"
|
|
191
|
-
end
|
|
192
|
-
raise TypeError.new(msg)
|
|
185
|
+
raise TypeError.new("Passed `nil` into T.must")
|
|
193
186
|
rescue TypeError => e # raise into rescue to ensure e.backtrace is populated
|
|
194
187
|
T::Private::ErrorHandler.handle_inline_type_error(e)
|
|
195
188
|
end
|
data/lib/types/configuration.rb
CHANGED
|
@@ -17,6 +17,19 @@ module T::Configuration
|
|
|
17
17
|
T::Private::RuntimeLevels.enable_checking_in_tests
|
|
18
18
|
end
|
|
19
19
|
|
|
20
|
+
# Configure the default checked level for a sig with no explicit `.checked`
|
|
21
|
+
# builder. When unset, the default checked level is `:always`.
|
|
22
|
+
#
|
|
23
|
+
# Note: setting this option is potentially dangerous! Sorbet can't check all
|
|
24
|
+
# code statically. The runtime checks complement the checks that Sorbet does
|
|
25
|
+
# statically, so that methods don't have to guard themselves from being
|
|
26
|
+
# called incorrectly by untyped code.
|
|
27
|
+
#
|
|
28
|
+
# @param [:never, :tests, :always] default_checked_level
|
|
29
|
+
def self.default_checked_level=(default_checked_level)
|
|
30
|
+
T::Private::RuntimeLevels.default_checked_level = default_checked_level
|
|
31
|
+
end
|
|
32
|
+
|
|
20
33
|
# Set a handler to handle `TypeError`s raised by any in-line type assertions,
|
|
21
34
|
# including `T.must`, `T.let`, `T.cast`, and `T.assert_type!`.
|
|
22
35
|
#
|
|
@@ -43,8 +43,8 @@ module T::Private::Methods
|
|
|
43
43
|
if decl.returns == ARG_NOT_PROVIDED
|
|
44
44
|
raise "Procs must specify a return type"
|
|
45
45
|
end
|
|
46
|
-
if decl.
|
|
47
|
-
raise "Procs cannot use .
|
|
46
|
+
if decl.on_failure != ARG_NOT_PROVIDED
|
|
47
|
+
raise "Procs cannot use .on_failure"
|
|
48
48
|
end
|
|
49
49
|
|
|
50
50
|
if decl.params == ARG_NOT_PROVIDED
|
|
@@ -224,7 +224,7 @@ module T::Private::Methods
|
|
|
224
224
|
bind: current_declaration.bind,
|
|
225
225
|
mode: current_declaration.mode,
|
|
226
226
|
check_level: current_declaration.checked,
|
|
227
|
-
|
|
227
|
+
on_failure: current_declaration.on_failure,
|
|
228
228
|
override_allow_incompatible: current_declaration.override_allow_incompatible,
|
|
229
229
|
generated: current_declaration.generated,
|
|
230
230
|
)
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
# typed: true
|
|
3
3
|
|
|
4
4
|
module T::Private::Methods
|
|
5
|
-
Declaration = Struct.new(:mod, :params, :returns, :bind, :mode, :checked, :finalized, :
|
|
5
|
+
Declaration = Struct.new(:mod, :params, :returns, :bind, :mode, :checked, :finalized, :on_failure, :override_allow_incompatible, :type_parameters, :generated)
|
|
6
6
|
|
|
7
7
|
class DeclBuilder
|
|
8
8
|
attr_reader :decl
|
|
@@ -25,7 +25,7 @@ module T::Private::Methods
|
|
|
25
25
|
Modes.standard, # mode
|
|
26
26
|
ARG_NOT_PROVIDED, # checked
|
|
27
27
|
false, # finalized
|
|
28
|
-
ARG_NOT_PROVIDED, #
|
|
28
|
+
ARG_NOT_PROVIDED, # on_failure
|
|
29
29
|
nil, # override_allow_incompatible
|
|
30
30
|
ARG_NOT_PROVIDED, # type_parameters
|
|
31
31
|
ARG_NOT_PROVIDED, # generated
|
|
@@ -80,16 +80,13 @@ module T::Private::Methods
|
|
|
80
80
|
end
|
|
81
81
|
|
|
82
82
|
def checked(level)
|
|
83
|
-
if T.unsafe(true)
|
|
84
|
-
raise "The .checked API is unstable, so we don't want it used until we redesign it. To change Sorbet's runtime behavior, see https://sorbet.org/docs/tconfiguration"
|
|
85
|
-
end
|
|
86
83
|
check_live!
|
|
87
84
|
|
|
88
85
|
if !decl.checked.equal?(ARG_NOT_PROVIDED)
|
|
89
86
|
raise BuilderError.new("You can't call .checked multiple times in a signature.")
|
|
90
87
|
end
|
|
91
|
-
if !decl.
|
|
92
|
-
raise BuilderError.new("You can't use .checked with .
|
|
88
|
+
if level == :never && !decl.on_failure.equal?(ARG_NOT_PROVIDED)
|
|
89
|
+
raise BuilderError.new("You can't use .checked(:never) with .on_failure because .on_failure will have no effect.")
|
|
93
90
|
end
|
|
94
91
|
if !decl.generated.equal?(ARG_NOT_PROVIDED)
|
|
95
92
|
raise BuilderError.new("You can't use .checked with .generated.")
|
|
@@ -103,29 +100,20 @@ module T::Private::Methods
|
|
|
103
100
|
self
|
|
104
101
|
end
|
|
105
102
|
|
|
106
|
-
def
|
|
107
|
-
if T.unsafe(true)
|
|
108
|
-
raise "The .soft API is unstable, so we don't want it used until we redesign it. To change Sorbet's runtime behavior, see https://sorbet.org/docs/tconfiguration"
|
|
109
|
-
end
|
|
103
|
+
def on_failure(*args)
|
|
110
104
|
check_live!
|
|
111
105
|
|
|
112
|
-
if !decl.
|
|
113
|
-
raise BuilderError.new("You can't call .
|
|
106
|
+
if !decl.on_failure.equal?(ARG_NOT_PROVIDED)
|
|
107
|
+
raise BuilderError.new("You can't call .on_failure multiple times in a signature.")
|
|
114
108
|
end
|
|
115
|
-
if
|
|
116
|
-
raise BuilderError.new("You can't use .
|
|
109
|
+
if decl.checked == :never
|
|
110
|
+
raise BuilderError.new("You can't use .on_failure with .checked(:never) because .on_failure will have no effect.")
|
|
117
111
|
end
|
|
118
112
|
if !decl.generated.equal?(ARG_NOT_PROVIDED)
|
|
119
|
-
raise BuilderError.new("You can't use .
|
|
120
|
-
end
|
|
121
|
-
|
|
122
|
-
# TODO consider validating that :notify is a project that sentry knows about,
|
|
123
|
-
# as per https://git.corp.stripe.com/stripe-internal/pay-server/blob/master/lib/event/job/sentry_job.rb#L125
|
|
124
|
-
if !notify || notify == ''
|
|
125
|
-
raise BuilderError.new("You can't provide an empty notify to .soft().")
|
|
113
|
+
raise BuilderError.new("You can't use .on_failure with .generated.")
|
|
126
114
|
end
|
|
127
115
|
|
|
128
|
-
decl.
|
|
116
|
+
decl.on_failure = args
|
|
129
117
|
|
|
130
118
|
self
|
|
131
119
|
end
|
|
@@ -139,8 +127,8 @@ module T::Private::Methods
|
|
|
139
127
|
if !decl.checked.equal?(ARG_NOT_PROVIDED)
|
|
140
128
|
raise BuilderError.new("You can't use .generated with .checked.")
|
|
141
129
|
end
|
|
142
|
-
if !decl.
|
|
143
|
-
raise BuilderError.new("You can't use .generated with .
|
|
130
|
+
if !decl.on_failure.equal?(ARG_NOT_PROVIDED)
|
|
131
|
+
raise BuilderError.new("You can't use .generated with .on_failure.")
|
|
144
132
|
end
|
|
145
133
|
|
|
146
134
|
decl.generated = true
|
|
@@ -249,10 +237,14 @@ module T::Private::Methods
|
|
|
249
237
|
decl.bind = nil
|
|
250
238
|
end
|
|
251
239
|
if decl.checked.equal?(ARG_NOT_PROVIDED)
|
|
252
|
-
|
|
240
|
+
default_checked_level = T::Private::RuntimeLevels.default_checked_level
|
|
241
|
+
if default_checked_level == :never && !decl.on_failure.equal?(ARG_NOT_PROVIDED)
|
|
242
|
+
raise BuilderError.new("To use .on_failure you must additionally call .checked(:tests) or .checked(:always), otherwise, the .on_failure has no effect.")
|
|
243
|
+
end
|
|
244
|
+
decl.checked = default_checked_level
|
|
253
245
|
end
|
|
254
|
-
if decl.
|
|
255
|
-
decl.
|
|
246
|
+
if decl.on_failure.equal?(ARG_NOT_PROVIDED)
|
|
247
|
+
decl.on_failure = nil
|
|
256
248
|
end
|
|
257
249
|
if decl.generated.equal?(ARG_NOT_PROVIDED)
|
|
258
250
|
decl.generated = false
|
|
@@ -5,7 +5,7 @@ class T::Private::Methods::Signature
|
|
|
5
5
|
attr_reader :method, :method_name, :arg_types, :kwarg_types, :block_type, :block_name,
|
|
6
6
|
:rest_type, :rest_name, :keyrest_type, :keyrest_name, :bind,
|
|
7
7
|
:return_type, :mode, :req_arg_count, :req_kwarg_names, :has_rest, :has_keyrest,
|
|
8
|
-
:check_level, :generated, :parameters, :
|
|
8
|
+
:check_level, :generated, :parameters, :on_failure, :override_allow_incompatible, :ever_failed
|
|
9
9
|
|
|
10
10
|
def self.new_untyped(method:, mode: T::Private::Methods::Modes.untyped, parameters: method.parameters)
|
|
11
11
|
# Using `Untyped` ensures we'll get an error if we ever try validation on these.
|
|
@@ -24,7 +24,7 @@ class T::Private::Methods::Signature
|
|
|
24
24
|
mode: mode,
|
|
25
25
|
check_level: :never,
|
|
26
26
|
parameters: parameters,
|
|
27
|
-
|
|
27
|
+
on_failure: nil,
|
|
28
28
|
)
|
|
29
29
|
end
|
|
30
30
|
|
|
@@ -32,7 +32,7 @@ class T::Private::Methods::Signature
|
|
|
32
32
|
@ever_failed = true
|
|
33
33
|
end
|
|
34
34
|
|
|
35
|
-
def initialize(method:, method_name:, raw_arg_types:, raw_return_type:, bind:, mode:, check_level:, parameters: method.parameters,
|
|
35
|
+
def initialize(method:, method_name:, raw_arg_types:, raw_return_type:, bind:, mode:, check_level:, parameters: method.parameters, on_failure:, generated: false, override_allow_incompatible: false)
|
|
36
36
|
@method = method
|
|
37
37
|
@method_name = method_name
|
|
38
38
|
@arg_types = []
|
|
@@ -52,7 +52,7 @@ class T::Private::Methods::Signature
|
|
|
52
52
|
@has_rest = false
|
|
53
53
|
@has_keyrest = false
|
|
54
54
|
@parameters = parameters
|
|
55
|
-
@
|
|
55
|
+
@on_failure = on_failure
|
|
56
56
|
@override_allow_incompatible = override_allow_incompatible
|
|
57
57
|
@generated = generated
|
|
58
58
|
@ever_failed = false
|
|
@@ -17,6 +17,9 @@ module T::Private::RuntimeLevels
|
|
|
17
17
|
@check_tests = false
|
|
18
18
|
@wrapped_tests_with_validation = false
|
|
19
19
|
|
|
20
|
+
@has_read_default_checked_level = false
|
|
21
|
+
@default_checked_level = :always
|
|
22
|
+
|
|
20
23
|
def self.check_tests?
|
|
21
24
|
# Assume that this code path means that some `sig.checked(:tests)`
|
|
22
25
|
# has been wrapped (or not wrapped) already, which is a trapdoor
|
|
@@ -35,6 +38,18 @@ module T::Private::RuntimeLevels
|
|
|
35
38
|
_toggle_checking_tests(true)
|
|
36
39
|
end
|
|
37
40
|
|
|
41
|
+
def self.default_checked_level
|
|
42
|
+
@has_read_default_checked_level = true
|
|
43
|
+
@default_checked_level
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def self.default_checked_level=(default_checked_level)
|
|
47
|
+
if @has_read_default_checked_level
|
|
48
|
+
raise "Set the default checked level earlier. There are already some methods whose sig blocks have evaluated which would not be affected by the new default."
|
|
49
|
+
end
|
|
50
|
+
@default_checked_level = default_checked_level
|
|
51
|
+
end
|
|
52
|
+
|
|
38
53
|
def self._toggle_checking_tests(checked)
|
|
39
54
|
@check_tests = checked
|
|
40
55
|
end
|
|
@@ -18,7 +18,7 @@ class T::Props::Decorator
|
|
|
18
18
|
|
|
19
19
|
class NoRulesError < StandardError; end
|
|
20
20
|
|
|
21
|
-
sig {params(klass: DecoratedClass).void}
|
|
21
|
+
T::Sig::WithoutRuntime.sig {params(klass: DecoratedClass).void}
|
|
22
22
|
def initialize(klass)
|
|
23
23
|
@class = klass
|
|
24
24
|
klass.plugins.each do |mod|
|
|
@@ -27,7 +27,7 @@ class T::Props::Decorator
|
|
|
27
27
|
end
|
|
28
28
|
|
|
29
29
|
# prop stuff
|
|
30
|
-
sig {returns(T::Hash[Symbol, Rules])}
|
|
30
|
+
sig {returns(T::Hash[Symbol, Rules]).checked(:never)}
|
|
31
31
|
def props
|
|
32
32
|
@props ||= {}.freeze
|
|
33
33
|
end
|
|
@@ -44,7 +44,7 @@ class T::Props::Decorator
|
|
|
44
44
|
sig {returns(T::Array[Symbol])}
|
|
45
45
|
def all_props; props.keys; end
|
|
46
46
|
|
|
47
|
-
sig {params(prop: T.any(Symbol, String)).returns(Rules)}
|
|
47
|
+
sig {params(prop: T.any(Symbol, String)).returns(Rules).checked(:never)}
|
|
48
48
|
def prop_rules(prop); props[prop.to_sym] || raise("No such prop: #{prop.inspect}"); end
|
|
49
49
|
|
|
50
50
|
sig {params(prop: Symbol, rules: Rules).void}
|
|
@@ -80,7 +80,7 @@ class T::Props::Decorator
|
|
|
80
80
|
}
|
|
81
81
|
end
|
|
82
82
|
|
|
83
|
-
sig {returns(DecoratedClass)}
|
|
83
|
+
sig {returns(DecoratedClass).checked(:never)}
|
|
84
84
|
def decorated_class; @class; end
|
|
85
85
|
|
|
86
86
|
# Accessors
|
|
@@ -94,6 +94,7 @@ class T::Props::Decorator
|
|
|
94
94
|
rules: T.nilable(Rules)
|
|
95
95
|
)
|
|
96
96
|
.returns(T.untyped)
|
|
97
|
+
.checked(:never)
|
|
97
98
|
end
|
|
98
99
|
def get(instance, prop, rules=props[prop.to_sym])
|
|
99
100
|
# For backwards compatibility, fall back to reconstructing the accessor key
|
|
@@ -111,6 +112,7 @@ class T::Props::Decorator
|
|
|
111
112
|
rules: T.nilable(Rules)
|
|
112
113
|
)
|
|
113
114
|
.void
|
|
115
|
+
.checked(:never)
|
|
114
116
|
end
|
|
115
117
|
def set(instance, prop, value, rules=props[prop.to_sym])
|
|
116
118
|
# For backwards compatibility, fall back to reconstructing the accessor key
|
|
@@ -119,7 +121,7 @@ class T::Props::Decorator
|
|
|
119
121
|
end
|
|
120
122
|
|
|
121
123
|
# Use this to validate that a value will validate for a given prop. Useful for knowing whether a value can be set on a model without setting it.
|
|
122
|
-
sig {params(prop: Symbol, val: T.untyped).void}
|
|
124
|
+
sig {params(prop: Symbol, val: T.untyped).void.checked(:never)}
|
|
123
125
|
def validate_prop_value(prop, val)
|
|
124
126
|
# This implements a 'public api' on document so that we don't allow callers to pass in rules
|
|
125
127
|
# Rules seem like an implementation detail so it seems good to now allow people to specify them manually.
|
|
@@ -127,7 +129,7 @@ class T::Props::Decorator
|
|
|
127
129
|
end
|
|
128
130
|
|
|
129
131
|
# Passing in rules here is purely a performance optimization.
|
|
130
|
-
sig {params(prop: Symbol, val: T.untyped, rules: Rules).void}
|
|
132
|
+
sig {params(prop: Symbol, val: T.untyped, rules: Rules).void.checked(:never)}
|
|
131
133
|
private def check_prop_type(prop, val, rules=prop_rules(prop))
|
|
132
134
|
type_object = rules.fetch(:type_object)
|
|
133
135
|
type = rules.fetch(:type)
|
|
@@ -173,6 +175,7 @@ class T::Props::Decorator
|
|
|
173
175
|
rules: T.nilable(Rules)
|
|
174
176
|
)
|
|
175
177
|
.void
|
|
178
|
+
.checked(:never)
|
|
176
179
|
end
|
|
177
180
|
def prop_set(instance, prop, val, rules=prop_rules(prop))
|
|
178
181
|
check_prop_type(prop, val, T.must(rules))
|
|
@@ -188,6 +191,7 @@ class T::Props::Decorator
|
|
|
188
191
|
rules: T.nilable(Rules)
|
|
189
192
|
)
|
|
190
193
|
.returns(T.untyped)
|
|
194
|
+
.checked(:never)
|
|
191
195
|
end
|
|
192
196
|
def prop_get(instance, prop, rules=props[prop.to_sym])
|
|
193
197
|
val = get(instance, prop, rules)
|
|
@@ -222,6 +226,7 @@ class T::Props::Decorator
|
|
|
222
226
|
opts: Hash
|
|
223
227
|
)
|
|
224
228
|
.returns(T.untyped)
|
|
229
|
+
.checked(:never)
|
|
225
230
|
end
|
|
226
231
|
def foreign_prop_get(instance, prop, foreign_class, rules=props[prop.to_sym], opts={})
|
|
227
232
|
return if !(value = prop_get(instance, prop, rules))
|
|
@@ -325,7 +330,6 @@ class T::Props::Decorator
|
|
|
325
330
|
.void
|
|
326
331
|
end
|
|
327
332
|
def prop_defined(name, cls, rules={})
|
|
328
|
-
# TODO(jerry): Create similar soft assertions against false
|
|
329
333
|
if rules[:optional] == true
|
|
330
334
|
T::Configuration.hard_assert_handler(
|
|
331
335
|
'Use of `optional: true` is deprecated, please use `T.nilable(...)` instead.',
|
|
@@ -776,7 +780,7 @@ class T::Props::Decorator
|
|
|
776
780
|
#
|
|
777
781
|
# This gets called when a module or class that extends T::Props gets included, extended,
|
|
778
782
|
# prepended, or inherited.
|
|
779
|
-
sig {params(child: DecoratedClass).void}
|
|
783
|
+
T::Sig::WithoutRuntime.sig {params(child: DecoratedClass).void}
|
|
780
784
|
def model_inherited(child)
|
|
781
785
|
child.extend(T::Props::ClassMethods)
|
|
782
786
|
child.plugins.concat(decorated_class.plugins)
|
|
@@ -797,7 +801,7 @@ class T::Props::Decorator
|
|
|
797
801
|
end
|
|
798
802
|
end
|
|
799
803
|
|
|
800
|
-
sig {params(mod: Module).void}
|
|
804
|
+
T::Sig::WithoutRuntime.sig {params(mod: Module).void}
|
|
801
805
|
def plugin(mod)
|
|
802
806
|
decorated_class.plugins << mod
|
|
803
807
|
Private.apply_class_methods(mod, decorated_class)
|
|
@@ -70,6 +70,7 @@ module T::Props::PrettyPrintable
|
|
|
70
70
|
sig do
|
|
71
71
|
params(instance: T::Props::PrettyPrintable, prop: Symbol, multiline: T::Boolean, indent: String)
|
|
72
72
|
.returns(String)
|
|
73
|
+
.checked(:never)
|
|
73
74
|
end
|
|
74
75
|
private def inspect_prop_value(instance, prop, multiline:, indent:)
|
|
75
76
|
val = T.unsafe(self).get(instance, prop)
|
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.
|
|
4
|
+
version: 0.4.4375
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Stripe
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2019-
|
|
11
|
+
date: 2019-07-02 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: minitest
|