Skip to content

Commit 15a2b2b

Browse files
fix: correctly instantiate sorbet type aliases for enums and unions
1 parent 54b6422 commit 15a2b2b

File tree

131 files changed

+252
-1462
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

131 files changed

+252
-1462
lines changed

lib/openai/internal/type/array_of.rb

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ module Type
1212
# Array of items of a given type.
1313
class ArrayOf
1414
include OpenAI::Internal::Type::Converter
15+
include OpenAI::Internal::Util::SorbetRuntimeSupport
1516

1617
private_class_method :new
1718

@@ -110,6 +111,13 @@ def dump(value, state:)
110111
end
111112
end
112113

114+
# @api private
115+
#
116+
# @return [Object]
117+
def to_sorbet_type
118+
T::Array[OpenAI::Internal::Util::SorbetRuntimeSupport.to_sorbet_type(item_type)]
119+
end
120+
113121
# @api private
114122
#
115123
# @return [generic<Elem>]

lib/openai/internal/type/base_model.rb

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -304,6 +304,13 @@ def dump(value, state:)
304304

305305
acc
306306
end
307+
308+
# @api private
309+
#
310+
# @return [Object]
311+
def to_sorbet_type
312+
self
313+
end
307314
end
308315

309316
class << self

lib/openai/internal/type/boolean.rb

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ module Type
1010
# Ruby has no Boolean class; this is something for models to refer to.
1111
class Boolean
1212
extend OpenAI::Internal::Type::Converter
13+
extend OpenAI::Internal::Util::SorbetRuntimeSupport
1314

1415
private_class_method :new
1516

@@ -56,6 +57,13 @@ def coerce(value, state:)
5657
# @option state [Boolean] :can_retry
5758
#
5859
# @return [Boolean, Object]
60+
61+
# @api private
62+
#
63+
# @return [Object]
64+
def to_sorbet_type
65+
T::Boolean
66+
end
5967
end
6068
end
6169
end

lib/openai/internal/type/enum.rb

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,18 @@ def coerce(value, state:)
112112
#
113113
# @return [Symbol, Object]
114114

115+
# @api private
116+
#
117+
# @return [Object]
118+
def to_sorbet_type
119+
case values
120+
in []
121+
T.noreturn
122+
in [value, *_]
123+
T.all(OpenAI::Internal::Util::SorbetRuntimeSupport.to_sorbet_type(value), self)
124+
end
125+
end
126+
115127
# @api private
116128
#
117129
# @param depth [Integer]

lib/openai/internal/type/file_input.rb

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,13 @@ def dump(value, state:)
8989

9090
value
9191
end
92+
93+
# @api private
94+
#
95+
# @return [Object]
96+
def to_sorbet_type
97+
T.any(Pathname, StringIO, IO, String, OpenAI::FilePart)
98+
end
9299
end
93100
end
94101
end

lib/openai/internal/type/hash_of.rb

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ module Type
1212
# Hash of items of a given type.
1313
class HashOf
1414
include OpenAI::Internal::Type::Converter
15+
include OpenAI::Internal::Util::SorbetRuntimeSupport
1516

1617
private_class_method :new
1718

@@ -130,6 +131,13 @@ def dump(value, state:)
130131
end
131132
end
132133

134+
# @api private
135+
#
136+
# @return [Object]
137+
def to_sorbet_type
138+
T::Hash[OpenAI::Internal::Util::SorbetRuntimeSupport.to_sorbet_type(item_type)]
139+
end
140+
133141
# @api private
134142
#
135143
# @return [generic<Elem>]

lib/openai/internal/type/union.rb

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,18 @@ def dump(value, state:)
216216
super
217217
end
218218

219+
# @api private
220+
#
221+
# @return [Object]
222+
def to_sorbet_type
223+
case (v = variants)
224+
in []
225+
T.noreturn
226+
else
227+
T.any(*v.map { OpenAI::Internal::Util::SorbetRuntimeSupport.to_sorbet_type(_1) })
228+
end
229+
end
230+
219231
# rubocop:enable Style/CaseEquality
220232
# rubocop:enable Style/HashEachMethods
221233

lib/openai/internal/type/unknown.rb

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ module Type
1010
# When we don't know what to expect for the value.
1111
class Unknown
1212
extend OpenAI::Internal::Type::Converter
13+
extend OpenAI::Internal::Util::SorbetRuntimeSupport
1314

1415
# rubocop:disable Lint/UnusedMethodArgument
1516

@@ -58,6 +59,13 @@ def coerce(value, state:)
5859
# @option state [Boolean] :can_retry
5960
#
6061
# @return [Object]
62+
63+
# @api private
64+
#
65+
# @return [Object]
66+
def to_sorbet_type
67+
T.anything
68+
end
6169
end
6270

6371
# rubocop:enable Lint/UnusedMethodArgument

lib/openai/internal/util.rb

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,23 @@ module Util
99
# @return [Float]
1010
def self.monotonic_secs = Process.clock_gettime(Process::CLOCK_MONOTONIC)
1111

12+
# @api private
13+
#
14+
# @param ns [Module, Class]
15+
#
16+
# @return [Enumerable<Module, Class>]
17+
def self.walk_namespaces(ns)
18+
ns.constants(false).lazy.flat_map do
19+
case (c = ns.const_get(_1, false))
20+
in Module | Class
21+
walk_namespaces(c)
22+
else
23+
[]
24+
end
25+
end
26+
.chain([ns])
27+
end
28+
1229
class << self
1330
# @api private
1431
#
@@ -826,11 +843,39 @@ def const_missing(name)
826843
sorbet_runtime_constants.fetch(name).call
827844
end
828845

846+
# @api private
847+
#
848+
# @param name [Symbol]
849+
#
850+
# @return [Boolean]
851+
def sorbet_constant_defined?(name) = sorbet_runtime_constants.key?(name)
852+
829853
# @api private
830854
#
831855
# @param name [Symbol]
832856
# @param blk [Proc]
833857
def define_sorbet_constant!(name, &blk) = sorbet_runtime_constants.store(name, blk)
858+
859+
# @api private
860+
#
861+
# @return [Object]
862+
def to_sorbet_type = raise NotImplementedError
863+
864+
class << self
865+
# @api private
866+
#
867+
# @param type [OpenAI::Internal::Util::SorbetRuntimeSupport, Object]
868+
#
869+
# @return [Object]
870+
def to_sorbet_type(type)
871+
case type
872+
in OpenAI::Internal::Util::SorbetRuntimeSupport
873+
type.to_sorbet_type
874+
else
875+
type
876+
end
877+
end
878+
end
834879
end
835880

836881
extend OpenAI::Internal::Util::SorbetRuntimeSupport

lib/openai/models.rb

Lines changed: 30 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -5,29 +5,40 @@ module OpenAI
55
cls.define_sorbet_constant!(:OrHash) { T.type_alias { T.any(cls, OpenAI::Internal::AnyHash) } }
66
end
77

8-
[
9-
*OpenAI::Internal::Type::Enum.included_modules,
10-
*OpenAI::Internal::Type::Union.included_modules
11-
].each do |cls|
12-
cls.constants.each do |name|
13-
case cls.const_get(name)
14-
in true | false
15-
cls.define_sorbet_constant!(:TaggedBoolean) { T.type_alias { T.all(T::Boolean, cls) } }
16-
cls.define_sorbet_constant!(:OrBoolean) { T.type_alias { T::Boolean } }
17-
in Integer
18-
cls.define_sorbet_constant!(:TaggedInteger) { T.type_alias { T.all(Integer, cls) } }
19-
cls.define_sorbet_constant!(:OrInteger) { T.type_alias { Integer } }
20-
in Float
21-
cls.define_sorbet_constant!(:TaggedFloat) { T.type_alias { T.all(Float, cls) } }
22-
cls.define_sorbet_constant!(:OrFloat) { T.type_alias { Float } }
23-
in Symbol
24-
cls.define_sorbet_constant!(:TaggedSymbol) { T.type_alias { T.all(Symbol, cls) } }
25-
cls.define_sorbet_constant!(:OrSymbol) { T.type_alias { T.any(Symbol, String) } }
26-
else
8+
OpenAI::Internal::Util.walk_namespaces(OpenAI::Models).each do |mod|
9+
case mod
10+
in OpenAI::Internal::Type::Enum | OpenAI::Internal::Type::Union
11+
mod.constants.each do |name|
12+
case mod.const_get(name)
13+
in true | false
14+
mod.define_sorbet_constant!(:TaggedBoolean) { T.type_alias { T.all(T::Boolean, mod) } }
15+
mod.define_sorbet_constant!(:OrBoolean) { T.type_alias { T::Boolean } }
16+
in Integer
17+
mod.define_sorbet_constant!(:TaggedInteger) { T.type_alias { T.all(Integer, mod) } }
18+
mod.define_sorbet_constant!(:OrInteger) { T.type_alias { Integer } }
19+
in Float
20+
mod.define_sorbet_constant!(:TaggedFloat) { T.type_alias { T.all(Float, mod) } }
21+
mod.define_sorbet_constant!(:OrFloat) { T.type_alias { Float } }
22+
in Symbol
23+
mod.define_sorbet_constant!(:TaggedSymbol) { T.type_alias { T.all(Symbol, mod) } }
24+
mod.define_sorbet_constant!(:OrSymbol) { T.type_alias { T.any(Symbol, String) } }
25+
else
26+
end
2727
end
28+
else
2829
end
2930
end
3031

32+
OpenAI::Internal::Util.walk_namespaces(OpenAI::Models)
33+
.lazy
34+
.grep(OpenAI::Internal::Type::Union)
35+
.each do |mod|
36+
const = :Variants
37+
next if mod.sorbet_constant_defined?(const)
38+
39+
mod.define_sorbet_constant!(const) { T.type_alias { mod.to_sorbet_type } }
40+
end
41+
3142
AllModels = OpenAI::Models::AllModels
3243

3344
Audio = OpenAI::Models::Audio

0 commit comments

Comments
 (0)