sorbet-runtime 0.5.5843 → 0.5.5845
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 +5 -2
- data/lib/types/private/casts.rb +27 -0
- data/lib/types/private/types/type_alias.rb +5 -0
- data/lib/types/props/private/setter_factory.rb +12 -2
- data/lib/types/types/base.rb +13 -0
- data/lib/types/types/fixed_array.rb +16 -0
- data/lib/types/types/fixed_hash.rb +8 -0
- data/lib/types/types/intersection.rb +5 -0
- data/lib/types/types/simple.rb +17 -0
- data/lib/types/types/typed_array.rb +6 -1
- data/lib/types/types/typed_enumerable.rb +10 -5
- data/lib/types/types/typed_enumerator.rb +6 -1
- data/lib/types/types/typed_hash.rb +6 -1
- data/lib/types/types/typed_range.rb +6 -1
- data/lib/types/types/typed_set.rb +6 -1
- data/lib/types/types/union.rb +35 -0
- data/lib/types/utils.rb +2 -2
- 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: 7ed7cf6960b963bcdb3578b9c02558381dc17b409ac335e47737aa2c01f2bab9
|
4
|
+
data.tar.gz: da99d802502bbb2b64d6360bd2773559033dab41062e9ffbcc01699d55b8bc15
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 84445df7b4c62dc7f2770c0751c4b5aa9ab67e4dd00e6df257497eb59dc6d399a0576154b221509e576a96ad2953e20b87509a3f229f691a088178163b5ff286
|
7
|
+
data.tar.gz: 14021ce8b6add25886a802dc6ace9cd4eb4d7495e8d44239ebf573aa2a5d27cdd97e579a0ee752e27afe10f0b5b6207e96c898b9000b7986869cba2f0904f109
|
data/lib/types/_types.rb
CHANGED
@@ -26,12 +26,15 @@
|
|
26
26
|
module T
|
27
27
|
# T.any(<Type>, <Type>, ...) -- matches any of the types listed
|
28
28
|
def self.any(type_a, type_b, *types)
|
29
|
-
T::
|
29
|
+
type_a = T::Utils.coerce(type_a)
|
30
|
+
type_b = T::Utils.coerce(type_b)
|
31
|
+
types = types.map {|t| T::Utils.coerce(t)} if !types.empty?
|
32
|
+
T::Types::Union::Private::Pool.union_of_types(type_a, type_b, types)
|
30
33
|
end
|
31
34
|
|
32
35
|
# Shorthand for T.any(type, NilClass)
|
33
36
|
def self.nilable(type)
|
34
|
-
T::Types::Union.
|
37
|
+
T::Types::Union::Private::Pool.union_of_types(T::Utils.coerce(type), T::Utils::Nilable::NIL_TYPE)
|
35
38
|
end
|
36
39
|
|
37
40
|
# Matches any object. In the static checker, T.untyped allows any
|
data/lib/types/private/casts.rb
CHANGED
@@ -2,6 +2,14 @@
|
|
2
2
|
# typed: false
|
3
3
|
|
4
4
|
module T::Private
|
5
|
+
# Dynamically confirm that `value` is recursively a valid value of
|
6
|
+
# type `type`, including recursively through collections. Note that
|
7
|
+
# in some cases this runtime check can be very expensive, especially
|
8
|
+
# with large collections of objects.
|
9
|
+
def self.check_type_recursive!(value, type)
|
10
|
+
T::Private::Casts.cast_recursive(value, type, cast_method: "T.check_type_recursive!")
|
11
|
+
end
|
12
|
+
|
5
13
|
module Casts
|
6
14
|
def self.cast(value, type, cast_method:)
|
7
15
|
begin
|
@@ -18,5 +26,24 @@ module T::Private
|
|
18
26
|
value
|
19
27
|
end
|
20
28
|
end
|
29
|
+
|
30
|
+
# there's a lot of shared logic with the above one, but factoring
|
31
|
+
# it out like this makes it easier to hopefully one day delete
|
32
|
+
# this one
|
33
|
+
def self.cast_recursive(value, type, cast_method:)
|
34
|
+
begin
|
35
|
+
error = T::Utils.coerce(type).error_message_for_obj_recursive(value)
|
36
|
+
return value unless error
|
37
|
+
|
38
|
+
caller_loc = T.must(caller_locations(2..2)).first
|
39
|
+
|
40
|
+
suffix = "Caller: #{T.must(caller_loc).path}:#{T.must(caller_loc).lineno}"
|
41
|
+
|
42
|
+
raise TypeError.new("#{cast_method}: #{error}\n#{suffix}")
|
43
|
+
rescue TypeError => e # raise into rescue to ensure e.backtrace is populated
|
44
|
+
T::Configuration.inline_type_error_handler(e)
|
45
|
+
value
|
46
|
+
end
|
47
|
+
end
|
21
48
|
end
|
22
49
|
end
|
@@ -52,7 +52,12 @@ module T::Props
|
|
52
52
|
end
|
53
53
|
private_class_method def self.non_nil_proc(prop, accessor_key, non_nil_type, klass, validate)
|
54
54
|
proc do |val|
|
55
|
-
|
55
|
+
# this use of recursively_valid? is intentional: unlike for
|
56
|
+
# methods, we want to make sure data at the 'edge'
|
57
|
+
# (e.g. models that go into databases or structs serialized
|
58
|
+
# from disk) are correct, so we use more thorough runtime
|
59
|
+
# checks there
|
60
|
+
if non_nil_type.recursively_valid?(val)
|
56
61
|
if validate
|
57
62
|
validate.call(prop, val)
|
58
63
|
end
|
@@ -83,7 +88,12 @@ module T::Props
|
|
83
88
|
proc do |val|
|
84
89
|
if val.nil?
|
85
90
|
instance_variable_set(accessor_key, nil)
|
86
|
-
|
91
|
+
# this use of recursively_valid? is intentional: unlike for
|
92
|
+
# methods, we want to make sure data at the 'edge'
|
93
|
+
# (e.g. models that go into databases or structs serialized
|
94
|
+
# from disk) are correct, so we use more thorough runtime
|
95
|
+
# checks there
|
96
|
+
elsif non_nil_type.recursively_valid?(val)
|
87
97
|
if validate
|
88
98
|
validate.call(prop, val)
|
89
99
|
end
|
data/lib/types/types/base.rb
CHANGED
@@ -16,6 +16,11 @@ module T::Types
|
|
16
16
|
end
|
17
17
|
end
|
18
18
|
|
19
|
+
# this will be redefined in certain subclasses
|
20
|
+
def recursively_valid?(obj)
|
21
|
+
valid?(obj)
|
22
|
+
end
|
23
|
+
|
19
24
|
def valid?(obj)
|
20
25
|
raise NotImplementedError
|
21
26
|
end
|
@@ -130,6 +135,14 @@ module T::Types
|
|
130
135
|
end
|
131
136
|
end
|
132
137
|
|
138
|
+
def error_message_for_obj_recursive(obj)
|
139
|
+
if recursively_valid?(obj)
|
140
|
+
nil
|
141
|
+
else
|
142
|
+
"Expected type #{self.name}, got #{describe_obj(obj)}"
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
133
146
|
def validate!(obj)
|
134
147
|
err = error_message_for_obj(obj)
|
135
148
|
raise TypeError.new(err) if err
|
@@ -17,6 +17,22 @@ module T::Types
|
|
17
17
|
"[#{@types.join(', ')}]"
|
18
18
|
end
|
19
19
|
|
20
|
+
# @override Base
|
21
|
+
def recursively_valid?(obj)
|
22
|
+
if obj.is_a?(Array) && obj.length == @types.length
|
23
|
+
i = 0
|
24
|
+
while i < @types.length
|
25
|
+
if !@types[i].recursively_valid?(obj[i])
|
26
|
+
return false
|
27
|
+
end
|
28
|
+
i += 1
|
29
|
+
end
|
30
|
+
true
|
31
|
+
else
|
32
|
+
false
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
20
36
|
# @override Base
|
21
37
|
def valid?(obj)
|
22
38
|
if obj.is_a?(Array) && obj.length == @types.length
|
@@ -16,6 +16,14 @@ module T::Types
|
|
16
16
|
"{#{@types.map {|(k, v)| "#{k}: #{v}"}.join(', ')}}"
|
17
17
|
end
|
18
18
|
|
19
|
+
# @override Base
|
20
|
+
def recursively_valid?(obj)
|
21
|
+
return false unless obj.is_a?(Hash)
|
22
|
+
return false if @types.any? {|key, type| !type.recursively_valid?(obj[key])}
|
23
|
+
return false if obj.any? {|key, _| !@types[key]}
|
24
|
+
true
|
25
|
+
end
|
26
|
+
|
19
27
|
# @override Base
|
20
28
|
def valid?(obj)
|
21
29
|
return false unless obj.is_a?(Hash)
|
@@ -23,6 +23,11 @@ module T::Types
|
|
23
23
|
"T.all(#{@types.map(&:name).sort.join(', ')})"
|
24
24
|
end
|
25
25
|
|
26
|
+
# @override Base
|
27
|
+
def recursively_valid?(obj)
|
28
|
+
@types.all? {|type| type.recursively_valid?(obj)}
|
29
|
+
end
|
30
|
+
|
26
31
|
# @override Base
|
27
32
|
def valid?(obj)
|
28
33
|
@types.all? {|type| type.valid?(obj)}
|
data/lib/types/types/simple.rb
CHANGED
@@ -29,5 +29,22 @@ module T::Types
|
|
29
29
|
false
|
30
30
|
end
|
31
31
|
end
|
32
|
+
|
33
|
+
def to_nilable
|
34
|
+
@nilable ||= T::Types::Union.new([self, T::Utils::Nilable::NIL_TYPE])
|
35
|
+
end
|
36
|
+
|
37
|
+
module Private
|
38
|
+
module Pool
|
39
|
+
def self.type_for_module(mod)
|
40
|
+
cached = mod.instance_variable_get(:@__as_sorbet_simple_type)
|
41
|
+
return cached if cached
|
42
|
+
|
43
|
+
type = Simple.new(mod)
|
44
|
+
mod.instance_variable_set(:@__as_sorbet_simple_type, type) unless mod.frozen?
|
45
|
+
type
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
32
49
|
end
|
33
50
|
end
|
@@ -13,10 +13,15 @@ module T::Types
|
|
13
13
|
end
|
14
14
|
|
15
15
|
# @override Base
|
16
|
-
def
|
16
|
+
def recursively_valid?(obj)
|
17
17
|
obj.is_a?(Array) && super
|
18
18
|
end
|
19
19
|
|
20
|
+
# @override Base
|
21
|
+
def valid?(obj)
|
22
|
+
obj.is_a?(Array)
|
23
|
+
end
|
24
|
+
|
20
25
|
def new(*args) # rubocop:disable PrisonGuard/BanBuiltinMethodOverride
|
21
26
|
Array.new(*T.unsafe(args))
|
22
27
|
end
|
@@ -23,13 +23,18 @@ module T::Types
|
|
23
23
|
|
24
24
|
# @override Base
|
25
25
|
def valid?(obj)
|
26
|
+
obj.is_a?(Enumerable)
|
27
|
+
end
|
28
|
+
|
29
|
+
# @override Base
|
30
|
+
def recursively_valid?(obj)
|
26
31
|
return false unless obj.is_a?(Enumerable)
|
27
32
|
case obj
|
28
33
|
when Array
|
29
34
|
begin
|
30
35
|
it = 0
|
31
36
|
while it < obj.count
|
32
|
-
return false unless @type.
|
37
|
+
return false unless @type.recursively_valid?(obj[it])
|
33
38
|
it += 1
|
34
39
|
end
|
35
40
|
return true
|
@@ -42,8 +47,8 @@ module T::Types
|
|
42
47
|
value_type = types[1]
|
43
48
|
obj.each_pair do |key, val|
|
44
49
|
# Some objects (I'm looking at you Rack::Utils::HeaderHash) don't
|
45
|
-
# iterate over a [key, value] array, so we can't juse use the @type.
|
46
|
-
return false if !key_type.
|
50
|
+
# iterate over a [key, value] array, so we can't juse use the @type.recursively_valid?(v)
|
51
|
+
return false if !key_type.recursively_valid?(key) || !value_type.recursively_valid?(val)
|
47
52
|
end
|
48
53
|
return true
|
49
54
|
when Enumerator
|
@@ -54,10 +59,10 @@ module T::Types
|
|
54
59
|
# boundlessness, it does not express a type. For example `(nil...nil)` is not a T::Range[NilClass], its a range
|
55
60
|
# of unknown types (T::Range[T.untyped]).
|
56
61
|
# Similarly, `(nil...1)` is not a `T::Range[T.nilable(Integer)]`, it's a boundless range of Integer.
|
57
|
-
(obj.begin.nil? || @type.
|
62
|
+
(obj.begin.nil? || @type.recursively_valid?(obj.begin)) && (obj.end.nil? || @type.recursively_valid?(obj.end))
|
58
63
|
when Set
|
59
64
|
obj.each do |item|
|
60
|
-
return false unless @type.
|
65
|
+
return false unless @type.recursively_valid?(item)
|
61
66
|
end
|
62
67
|
|
63
68
|
return true
|
@@ -15,10 +15,15 @@ module T::Types
|
|
15
15
|
end
|
16
16
|
|
17
17
|
# @override Base
|
18
|
-
def
|
18
|
+
def recursively_valid?(obj)
|
19
19
|
obj.is_a?(Enumerator) && super
|
20
20
|
end
|
21
21
|
|
22
|
+
# @override Base
|
23
|
+
def valid?(obj)
|
24
|
+
obj.is_a?(Enumerator)
|
25
|
+
end
|
26
|
+
|
22
27
|
def new(*args, &blk) # rubocop:disable PrisonGuard/BanBuiltinMethodOverride
|
23
28
|
T.unsafe(Enumerator).new(*args, &blk)
|
24
29
|
end
|
@@ -22,10 +22,15 @@ module T::Types
|
|
22
22
|
end
|
23
23
|
|
24
24
|
# @override Base
|
25
|
-
def
|
25
|
+
def recursively_valid?(obj)
|
26
26
|
obj.is_a?(Hash) && super
|
27
27
|
end
|
28
28
|
|
29
|
+
# @override Base
|
30
|
+
def valid?(obj)
|
31
|
+
obj.is_a?(Hash)
|
32
|
+
end
|
33
|
+
|
29
34
|
def new(*args, &blk) # rubocop:disable PrisonGuard/BanBuiltinMethodOverride
|
30
35
|
Hash.new(*T.unsafe(args), &blk) # rubocop:disable PrisonGuard/RestrictHashDefaults
|
31
36
|
end
|
@@ -15,10 +15,15 @@ module T::Types
|
|
15
15
|
end
|
16
16
|
|
17
17
|
# @override Base
|
18
|
-
def
|
18
|
+
def recursively_valid?(obj)
|
19
19
|
obj.is_a?(Range) && super
|
20
20
|
end
|
21
21
|
|
22
|
+
# @override Base
|
23
|
+
def valid?(obj)
|
24
|
+
obj.is_a?(Range)
|
25
|
+
end
|
26
|
+
|
22
27
|
def new(*args) # rubocop:disable PrisonGuard/BanBuiltinMethodOverride
|
23
28
|
T.unsafe(Range).new(*args)
|
24
29
|
end
|
@@ -15,10 +15,15 @@ module T::Types
|
|
15
15
|
end
|
16
16
|
|
17
17
|
# @override Base
|
18
|
-
def
|
18
|
+
def recursively_valid?(obj)
|
19
19
|
obj.is_a?(Set) && super
|
20
20
|
end
|
21
21
|
|
22
|
+
# @override Base
|
23
|
+
def valid?(obj)
|
24
|
+
obj.is_a?(Set)
|
25
|
+
end
|
26
|
+
|
22
27
|
def new(*args) # rubocop:disable PrisonGuard/BanBuiltinMethodOverride
|
23
28
|
Set.new(*T.unsafe(args))
|
24
29
|
end
|
data/lib/types/types/union.rb
CHANGED
@@ -42,6 +42,11 @@ module T::Types
|
|
42
42
|
end
|
43
43
|
end
|
44
44
|
|
45
|
+
# @override Base
|
46
|
+
def recursively_valid?(obj)
|
47
|
+
@types.any? {|type| type.recursively_valid?(obj)}
|
48
|
+
end
|
49
|
+
|
45
50
|
# @override Base
|
46
51
|
def valid?(obj)
|
47
52
|
@types.any? {|type| type.valid?(obj)}
|
@@ -52,5 +57,35 @@ module T::Types
|
|
52
57
|
raise "This should never be reached if you're going through `subtype_of?` (and you should be)"
|
53
58
|
end
|
54
59
|
|
60
|
+
module Private
|
61
|
+
module Pool
|
62
|
+
EMPTY_ARRAY = [].freeze
|
63
|
+
private_constant :EMPTY_ARRAY
|
64
|
+
|
65
|
+
# @param type_a [T::Types::Base]
|
66
|
+
# @param type_b [T::Types::Base]
|
67
|
+
# @param types [Array] optional array of additional T::Types::Base instances
|
68
|
+
def self.union_of_types(type_a, type_b, types=EMPTY_ARRAY)
|
69
|
+
if types.empty?
|
70
|
+
# We aren't guaranteed to detect a simple `T.nilable(<Module>)` type here
|
71
|
+
# in cases where there are duplicate types, nested unions, etc.
|
72
|
+
#
|
73
|
+
# That's ok, because this is an optimization which isn't necessary for
|
74
|
+
# correctness.
|
75
|
+
if type_b == T::Utils::Nilable::NIL_TYPE && type_a.is_a?(T::Types::Simple)
|
76
|
+
type_a.to_nilable
|
77
|
+
elsif type_a == T::Utils::Nilable::NIL_TYPE && type_b.is_a?(T::Types::Simple)
|
78
|
+
type_b.to_nilable
|
79
|
+
else
|
80
|
+
Union.new([type_a, type_b])
|
81
|
+
end
|
82
|
+
else
|
83
|
+
# This can't be a `T.nilable(<Module>)` case unless there are duplicates,
|
84
|
+
# which is possible but unexpected.
|
85
|
+
Union.new([type_a, type_b] + types)
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
55
90
|
end
|
56
91
|
end
|
data/lib/types/utils.rb
CHANGED
@@ -21,7 +21,7 @@ module T::Utils
|
|
21
21
|
elsif val == ::Range
|
22
22
|
T::Range[T.untyped]
|
23
23
|
elsif val.is_a?(Module)
|
24
|
-
T::Types::Simple.
|
24
|
+
T::Types::Simple::Private::Pool.type_for_module(val)
|
25
25
|
elsif val.is_a?(::Array)
|
26
26
|
T::Types::FixedArray.new(val) # rubocop:disable PrisonGuard/UseOpusTypesShortcut
|
27
27
|
elsif val.is_a?(::Hash)
|
@@ -162,7 +162,7 @@ module T::Utils
|
|
162
162
|
elsif classes.length > 1
|
163
163
|
T::Types::Union.new(classes)
|
164
164
|
else
|
165
|
-
T::Types::Simple.
|
165
|
+
T::Types::Simple::Private::Pool.type_for_module(classes.first)
|
166
166
|
end
|
167
167
|
end
|
168
168
|
|
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.5845
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Stripe
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-07-
|
11
|
+
date: 2020-07-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: minitest
|