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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c20d0628aa85a684b88e4737a8e717fe91a7f15d
4
- data.tar.gz: a5af90068a95344d3beeac78c6ad8d3ba334ad88
3
+ metadata.gz: 62d9529bff7ed508939f3a8afec4dd9b2795190c
4
+ data.tar.gz: 6101b7766ca75e44e1372931b124c9ad505bb4e1
5
5
  SHA512:
6
- metadata.gz: 85dd318b56ab855f315742cbd5e3ea380990aa6a377be7d6fee40f0ac7fa5ac8f388abfb51fa0b2aea8af0c89c7df15857983bd3c799f281ccf7b20557832c4b
7
- data.tar.gz: 3f8f068484b137a255cf122a5e94c36799410d4207f352e6ba881d7cd1d58b9f11d2f7b52a6f32cee52fa41cd69c40d2fa60f0cec75c538582c01e39e5a476d0
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), msg: T.nilable(String)).returns(A)}
180
- def self.must(arg, msg=nil)
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
- if msg
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
@@ -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.soft_notify != ARG_NOT_PROVIDED
47
- raise "Procs cannot use .soft"
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
- soft_notify: current_declaration.soft_notify,
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, :soft_notify, :override_allow_incompatible, :type_parameters, :generated)
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, # soft_notify
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.soft_notify.equal?(ARG_NOT_PROVIDED)
92
- raise BuilderError.new("You can't use .checked with .soft.")
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 soft(notify:)
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.soft_notify.equal?(ARG_NOT_PROVIDED)
113
- raise BuilderError.new("You can't call .soft multiple times in a signature.")
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 !decl.checked.equal?(ARG_NOT_PROVIDED)
116
- raise BuilderError.new("You can't use .soft with .checked.")
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 .soft with .generated.")
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.soft_notify = notify
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.soft_notify.equal?(ARG_NOT_PROVIDED)
143
- raise BuilderError.new("You can't use .generated with .soft.")
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
- decl.checked = :always
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.soft_notify.equal?(ARG_NOT_PROVIDED)
255
- decl.soft_notify = nil
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, :soft_notify, :override_allow_incompatible, :ever_failed
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
- soft_notify: nil,
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, soft_notify:, generated: false, override_allow_incompatible: false)
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
- @soft_notify = soft_notify
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.4355
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-06-28 00:00:00.000000000 Z
11
+ date: 2019-07-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: minitest