1
1
from __future__ import annotations # Python < 3.10
2
2
3
- from typing import Any , List , Optional , Union , cast
3
+ from typing import Any , Callable , List , Optional , Union , cast
4
4
5
5
from ..language import (
6
6
ArgumentNode ,
52
52
__all__ = ["TypeInfo" , "TypeInfoVisitor" ]
53
53
54
54
55
+ GetFieldDefFn = Callable [
56
+ [GraphQLSchema , GraphQLType , FieldNode ], Optional [GraphQLField ]
57
+ ]
58
+
59
+
55
60
class TypeInfo :
56
61
"""Utility class for keeping track of type definitions.
57
62
@@ -65,11 +70,14 @@ def __init__(
65
70
self ,
66
71
schema : GraphQLSchema ,
67
72
initial_type : Optional [GraphQLType ] = None ,
73
+ get_field_def_fn : Optional [GetFieldDefFn ] = None ,
68
74
) -> None :
69
75
"""Initialize the TypeInfo for the given GraphQL schema.
70
76
71
77
Initial type may be provided in rare cases to facilitate traversals beginning
72
78
somewhere other than documents.
79
+
80
+ The optional last parameter is deprecated and will be removed in v3.3.
73
81
"""
74
82
self ._schema = schema
75
83
self ._type_stack : List [Optional [GraphQLOutputType ]] = []
@@ -80,6 +88,7 @@ def __init__(
80
88
self ._directive : Optional [GraphQLDirective ] = None
81
89
self ._argument : Optional [GraphQLArgument ] = None
82
90
self ._enum_value : Optional [GraphQLEnumValue ] = None
91
+ self ._get_field_def : GetFieldDefFn = get_field_def_fn or get_field_def
83
92
if initial_type :
84
93
if is_input_type (initial_type ):
85
94
self ._input_type_stack .append (cast (GraphQLInputType , initial_type ))
@@ -149,7 +158,7 @@ def enter_selection_set(self, node: SelectionSetNode) -> None:
149
158
def enter_field (self , node : FieldNode ) -> None :
150
159
parent_type = self .get_parent_type ()
151
160
if parent_type :
152
- field_def = get_field_def (self ._schema , parent_type , node )
161
+ field_def = self . _get_field_def (self ._schema , parent_type , node )
153
162
field_type = field_def .type if field_def else None
154
163
else :
155
164
field_def = field_type = None
@@ -268,24 +277,24 @@ def leave_enum_value(self) -> None:
268
277
269
278
270
279
def get_field_def (
271
- schema : GraphQLSchema , parent_type : GraphQLCompositeType , field_node : FieldNode
280
+ schema : GraphQLSchema , parent_type : GraphQLType , field_node : FieldNode
272
281
) -> Optional [GraphQLField ]:
273
282
"""Get field definition.
274
283
275
284
Not exactly the same as the executor's definition of
276
285
:func:`graphql.execution.get_field_def`, in this statically evaluated environment
277
286
we do not always have an Object type, and need to handle Interface and Union types.
278
287
"""
279
- field_name = field_node .name .value
280
- if field_name == "__schema" and schema .query_type is parent_type :
288
+ name = field_node .name .value
289
+ if name == "__schema" and schema .query_type is parent_type :
281
290
return SchemaMetaFieldDef
282
- if field_name == "__type" and schema .query_type is parent_type :
291
+ if name == "__type" and schema .query_type is parent_type :
283
292
return TypeMetaFieldDef
284
- if field_name == "__typename" and is_composite_type (parent_type ):
293
+ if name == "__typename" and is_composite_type (parent_type ):
285
294
return TypeNameMetaFieldDef
286
295
if is_object_type (parent_type ) or is_interface_type (parent_type ):
287
296
parent_type = cast (Union [GraphQLObjectType , GraphQLInterfaceType ], parent_type )
288
- return parent_type .fields .get (field_name )
297
+ return parent_type .fields .get (name )
289
298
return None
290
299
291
300
0 commit comments