5
5
import enum
6
6
import inspect
7
7
8
- from graphene import Field , Boolean , Dynamic , Enum , Float , Int , List , String , UUID , Union
8
+ from graphene import (
9
+ Field ,
10
+ Boolean ,
11
+ Dynamic ,
12
+ Enum ,
13
+ Float ,
14
+ Int ,
15
+ List ,
16
+ String ,
17
+ UUID ,
18
+ Union ,
19
+ )
9
20
from graphene .types .base import BaseType
21
+
10
22
try :
11
23
from graphene .types .decimal import Decimal as GrapheneDecimal
24
+
12
25
DECIMAL_SUPPORTED = True
13
26
except ImportError :
14
27
# graphene 2.1.5+ is required for Decimals
@@ -24,21 +37,21 @@ class ConversionError(TypeError):
24
37
pass
25
38
26
39
27
- # Placeholder for NoneType, so that we can easily reference it later
28
- TYPE_NONE = type (None )
29
-
30
-
31
40
def get_attr_resolver (attr_name : str ) -> T .Callable :
32
41
"""
33
42
Return a helper function that resolves a field with the given name by
34
43
looking it up as an attribute of the type we're trying to resolve it on.
35
44
"""
45
+
36
46
def _get_field (root , _info ):
37
47
return getattr (root , attr_name , None )
48
+
38
49
return _get_field
39
50
40
51
41
- def convert_pydantic_field (field : fields .Field , registry : Registry , ** field_kwargs ) -> Field :
52
+ def convert_pydantic_field (
53
+ field : fields .Field , registry : Registry , ** field_kwargs
54
+ ) -> Field :
42
55
"""
43
56
Convert a Pydantic model field into a Graphene type field that we can add
44
57
to the generated Graphene data model type.
@@ -58,7 +71,9 @@ def convert_pydantic_field(field: fields.Field, registry: Registry, **field_kwar
58
71
return Field (resolver = get_attr_resolver (field .name ), ** field_kwargs )
59
72
60
73
61
- def to_graphene_type (type_ : T .Type , field : fields .Field , registry : Registry = None ) -> BaseType : # noqa: C901
74
+ def to_graphene_type (
75
+ type_ : T .Type , field : fields .Field , registry : Registry = None
76
+ ) -> BaseType : # noqa: C901
62
77
"""
63
78
Map a native Python type to a Graphene-supported Field type, where possible.
64
79
"""
@@ -83,7 +98,7 @@ def to_graphene_type(type_: T.Type, field: fields.Field, registry: Registry = No
83
98
elif type_ in (tuple , list , set ):
84
99
# TODO: do Sets really belong here?
85
100
return List
86
- elif hasattr (type_ , ' __origin__' ):
101
+ elif hasattr (type_ , " __origin__" ):
87
102
return convert_generic_type (type_ , field , registry )
88
103
elif issubclass (type_ , enum .Enum ):
89
104
return Enum .from_enum (type_ )
@@ -98,7 +113,9 @@ def to_graphene_type(type_: T.Type, field: fields.Field, registry: Registry = No
98
113
)
99
114
100
115
101
- def convert_pydantic_type (type_ : T .Type , field : fields .Field , registry : Registry = None ) -> BaseType : # noqa: C901
116
+ def convert_pydantic_type (
117
+ type_ : T .Type , field : fields .Field , registry : Registry = None
118
+ ) -> BaseType : # noqa: C901
102
119
"""
103
120
Convert a Pydantic type to a Graphene Field type, including not just the
104
121
native Python type but any additional metadata (e.g. shape) that Pydantic
@@ -107,7 +124,12 @@ def convert_pydantic_type(type_: T.Type, field: fields.Field, registry: Registry
107
124
graphene_type = to_graphene_type (type_ , field , registry )
108
125
if field .shape == fields .Shape .SINGLETON :
109
126
return graphene_type
110
- elif field .shape in (fields .Shape .LIST , fields .Shape .TUPLE , fields .Shape .SEQUENCE , fields .Shape .SET ):
127
+ elif field .shape in (
128
+ fields .Shape .LIST ,
129
+ fields .Shape .TUPLE ,
130
+ fields .Shape .SEQUENCE ,
131
+ fields .Shape .SET ,
132
+ ):
111
133
# TODO: _should_ Sets remain here?
112
134
return List (graphene_type )
113
135
elif field .shape == fields .Shape .MAPPING :
@@ -142,16 +164,20 @@ def convert_union_type(type_, field, registry=None):
142
164
wrapped_types = type_ .__args__
143
165
# NOTE: a typing.Optional decomposes to a Union[None, T], so we can return
144
166
# the Graphene type for T; Pydantic will have already parsed it as optional
145
- if len (wrapped_types ) == 2 and TYPE_NONE in wrapped_types :
146
- native_type = next (x for x in wrapped_types if x != TYPE_NONE )
167
+ if len (wrapped_types ) == 2 and type ( None ) in wrapped_types :
168
+ native_type = next (x for x in wrapped_types if x != type ( None )) # noqa: E721
147
169
graphene_type = to_graphene_type (native_type , field , registry )
148
170
return graphene_type
149
171
else :
150
172
# Otherwise, we use a little metaprogramming -- create our own unique
151
173
# subclass of graphene.Union that knows its constituent Graphene types
152
- graphene_types = tuple (to_graphene_type (x , field , registry ) for x in wrapped_types )
153
- internal_meta = type ("Meta" , (), {'types' : graphene_types })
174
+ graphene_types = tuple (
175
+ to_graphene_type (x , field , registry ) for x in wrapped_types
176
+ )
177
+ internal_meta = type ("Meta" , (), {"types" : graphene_types })
154
178
155
179
union_class_name = "" .join (x .__name__ for x in wrapped_types )
156
- union_class = type (f"Union_{ union_class_name } " , (Union ,), {'Meta' : internal_meta })
180
+ union_class = type (
181
+ f"Union_{ union_class_name } " , (Union ,), {"Meta" : internal_meta }
182
+ )
157
183
return union_class
0 commit comments