24
24
from graphene .types .datetime import Date , DateTime , Time
25
25
from pydantic import BaseModel
26
26
from pydantic .fields import ModelField
27
+ from pydantic .typing import evaluate_forwardref
27
28
28
29
from .registry import Registry
29
30
from .util import construct_union_class_name
30
31
31
- try :
32
- # Pydantic pre-1.0
33
- from pydantic .fields import Shape
34
-
35
- SHAPE_SINGLETON = (Shape .SINGLETON ,)
36
- SHAPE_SEQUENTIAL = (
37
- Shape .LIST ,
38
- Shape .TUPLE ,
39
- Shape .TUPLE_ELLIPS ,
40
- Shape .SEQUENCE ,
41
- Shape .SET ,
42
- )
43
- SHAPE_MAPPING = (Shape .MAPPING ,)
44
- except ImportError :
45
- # Pydantic 1.0+
46
- from pydantic import fields
47
-
48
- SHAPE_SINGLETON = (fields .SHAPE_SINGLETON ,)
49
- SHAPE_SEQUENTIAL = (
50
- fields .SHAPE_LIST ,
51
- fields .SHAPE_TUPLE ,
52
- fields .SHAPE_TUPLE_ELLIPSIS ,
53
- fields .SHAPE_SEQUENCE ,
54
- fields .SHAPE_SET ,
32
+ from pydantic import fields
33
+
34
+ SHAPE_SINGLETON = (fields .SHAPE_SINGLETON ,)
35
+ SHAPE_SEQUENTIAL = (
36
+ fields .SHAPE_LIST ,
37
+ fields .SHAPE_TUPLE ,
38
+ fields .SHAPE_TUPLE_ELLIPSIS ,
39
+ fields .SHAPE_SEQUENCE ,
40
+ fields .SHAPE_SET ,
41
+ )
42
+
43
+ if hasattr (fields , "SHAPE_DICT" ):
44
+ SHAPE_MAPPING = T .cast (
45
+ T .Tuple , (fields .SHAPE_MAPPING , fields .SHAPE_DICT , fields .SHAPE_DEFAULTDICT )
55
46
)
56
- SHAPE_MAPPING = (fields .SHAPE_MAPPING ,)
47
+ else :
48
+ SHAPE_MAPPING = T .cast (T .Tuple , (fields .SHAPE_MAPPING ,))
57
49
58
50
59
51
try :
@@ -139,6 +131,10 @@ def convert_pydantic_field(
139
131
# - maybe even (Sphinx-style) parse attribute documentation
140
132
field_kwargs .setdefault ("description" , field .field_info .description )
141
133
134
+ # Somehow, this happens
135
+ if "type_" not in field_kwargs and "type" in field_kwargs :
136
+ field_kwargs ["type_" ] = field_kwargs .pop ("type" )
137
+
142
138
return Field (resolver = get_attr_resolver (field .name ), ** field_kwargs )
143
139
144
140
@@ -228,7 +224,7 @@ def find_graphene_type(
228
224
"See the README for more on forward references."
229
225
)
230
226
module_ns = sys .modules [sibling .__module__ ].__dict__
231
- resolved = type_ . _evaluate ( module_ns , None )
227
+ resolved = evaluate_forwardref ( type_ , module_ns , None )
232
228
# TODO: make this behavior optional. maybe this is a place for the TypeOptions to play a role?
233
229
if registry :
234
230
registry .add_placeholder_for_model (resolved )
@@ -267,7 +263,7 @@ def convert_generic_python_type(
267
263
return convert_union_type (
268
264
type_ , field , registry , parent_type = parent_type , model = model
269
265
)
270
- elif origin == T .Literal :
266
+ elif hasattr ( T , "Literal" ) and origin == T .Literal :
271
267
return convert_literal_type (
272
268
type_ , field , registry , parent_type = parent_type , model = model
273
269
)
@@ -338,6 +334,7 @@ def convert_union_type(
338
334
)
339
335
return union_cls
340
336
337
+
341
338
def convert_literal_type (
342
339
type_ : T .Type ,
343
340
field : ModelField ,
@@ -351,11 +348,7 @@ def convert_literal_type(
351
348
inner_types = type_ .__args__
352
349
# Here we'll expand the subtypes of this Literal into a corresponding more
353
350
# general scalar type.
354
- scalar_types = {
355
- type (x )
356
- for x in inner_types
357
- if x != NONE_TYPE
358
- }
351
+ scalar_types = {type (x ) for x in inner_types if x != NONE_TYPE }
359
352
graphene_scalar_types = [
360
353
convert_pydantic_type (x , field , registry , parent_type = parent_type , model = model )
361
354
for x in scalar_types
@@ -368,6 +361,10 @@ def convert_literal_type(
368
361
internal_meta_cls = type ("Meta" , (), {"types" : graphene_scalar_types })
369
362
370
363
union_cls = type (
371
- construct_union_class_name (scalar_types ), (Union ,), {"Meta" : internal_meta_cls }
364
+ construct_union_class_name (
365
+ sorted (scalar_types , key = lambda x : x .__class__ .__name__ )
366
+ ),
367
+ (Union ,),
368
+ {"Meta" : internal_meta_cls },
372
369
)
373
370
return union_cls
0 commit comments