6
6
Dict ,
7
7
Generic ,
8
8
List ,
9
+ Mapping ,
9
10
NamedTuple ,
10
11
Optional ,
11
12
TYPE_CHECKING ,
130
131
"GraphQLTypeResolver" ,
131
132
"GraphQLUnionType" ,
132
133
"GraphQLWrappingType" ,
133
- "Thunk" ,
134
+ "ThunkCollection" ,
135
+ "ThunkMapping" ,
134
136
]
135
137
136
138
@@ -287,15 +289,30 @@ def get_named_type(type_: Optional[GraphQLType]) -> Optional[GraphQLNamedType]:
287
289
return None
288
290
289
291
290
- def resolve_thunk (thunk : Any ) -> Any :
291
- """Resolve the given thunk.
292
+ T = TypeVar ("T" )
293
+
294
+ ThunkCollection = Union [Callable [[], Collection [T ]], Collection [T ]]
295
+ ThunkMapping = Union [Callable [[], Mapping [str , T ]], Mapping [str , T ]]
296
+
297
+
298
+ def resolve_thunk_collection (thunk : ThunkCollection [T ]) -> Collection [T ]:
299
+ """Resolve the given thunk for a collection.
292
300
293
301
Used while defining GraphQL types to allow for circular references in otherwise
294
302
immutable type definitions.
295
303
"""
296
304
return thunk () if callable (thunk ) else thunk
297
305
298
306
307
+ def resolve_thunk_mapping (thunk : ThunkMapping [T ]) -> Mapping [str , T ]:
308
+ """Resolve the given thunk for a mapping.
309
+
310
+ Used while defining GraphQL fields to allow for circular references in otherwise
311
+ immutable field definitions.
312
+ """
313
+ return thunk () if callable (thunk ) else thunk
314
+
315
+
299
316
GraphQLScalarSerializer = Callable [[Any ], Any ]
300
317
GraphQLScalarValueParser = Callable [[Any ], Any ]
301
318
GraphQLScalarLiteralParser = Callable [[ValueNode , Optional [Dict [str , Any ]]], Any ]
@@ -592,6 +609,8 @@ class GraphQLResolveInfo(NamedTuple):
592
609
# the context is passed as part of the GraphQLResolveInfo:
593
610
GraphQLIsTypeOfFn = Callable [[Any , GraphQLResolveInfo ], AwaitableOrValue [bool ]]
594
611
612
+ GraphQLFieldMap = Dict [str , GraphQLField ]
613
+
595
614
596
615
class GraphQLArgument :
597
616
"""Definition of a GraphQL argument"""
@@ -669,12 +688,6 @@ def is_required_argument(arg: GraphQLArgument) -> bool:
669
688
return is_non_null_type (arg .type ) and arg .default_value is Undefined
670
689
671
690
672
- T = TypeVar ("T" , bound = Collection )
673
- Thunk = Union [Callable [[], T ], T ]
674
-
675
- GraphQLFieldMap = Dict [str , GraphQLField ]
676
-
677
-
678
691
class GraphQLObjectType (GraphQLNamedType ):
679
692
"""Object Type Definition
680
693
@@ -710,8 +723,8 @@ class GraphQLObjectType(GraphQLNamedType):
710
723
def __init__ (
711
724
self ,
712
725
name : str ,
713
- fields : Thunk [ GraphQLFieldMap ],
714
- interfaces : Optional [Thunk [ Collection [ "GraphQLInterfaceType" ] ]] = None ,
726
+ fields : ThunkMapping [ GraphQLField ],
727
+ interfaces : Optional [ThunkCollection [ "GraphQLInterfaceType" ]] = None ,
715
728
is_type_of : Optional [GraphQLIsTypeOfFn ] = None ,
716
729
extensions : Optional [Dict [str , Any ]] = None ,
717
730
description : Optional [str ] = None ,
@@ -758,15 +771,15 @@ def __copy__(self) -> "GraphQLObjectType": # pragma: no cover
758
771
def fields (self ) -> GraphQLFieldMap :
759
772
"""Get provided fields, wrapping them as GraphQLFields if needed."""
760
773
try :
761
- fields = resolve_thunk (self ._fields )
774
+ fields = resolve_thunk_mapping (self ._fields )
762
775
except Exception as error :
763
776
raise TypeError (f"{ self .name } fields cannot be resolved. { error } " )
764
- if not isinstance (fields , dict ) or not all (
777
+ if not isinstance (fields , Mapping ) or not all (
765
778
isinstance (key , str ) for key in fields
766
779
):
767
780
raise TypeError (
768
781
f"{ self .name } fields must be specified"
769
- " as a dict with field names as keys."
782
+ " as a mapping with field names as keys."
770
783
)
771
784
if not all (
772
785
isinstance (value , GraphQLField ) or is_output_type (value )
@@ -776,16 +789,18 @@ def fields(self) -> GraphQLFieldMap:
776
789
f"{ self .name } fields must be GraphQLField or output type objects."
777
790
)
778
791
return {
779
- name : value if isinstance (value , GraphQLField ) else GraphQLField (value )
792
+ name : value
793
+ if isinstance (value , GraphQLField )
794
+ else GraphQLField (value ) # type: ignore
780
795
for name , value in fields .items ()
781
796
}
782
797
783
798
@cached_property
784
799
def interfaces (self ) -> List ["GraphQLInterfaceType" ]:
785
800
"""Get provided interfaces."""
786
801
try :
787
- interfaces : Collection ["GraphQLInterfaceType" ] = resolve_thunk (
788
- self ._interfaces
802
+ interfaces : Collection ["GraphQLInterfaceType" ] = resolve_thunk_collection (
803
+ self ._interfaces # type: ignore
789
804
)
790
805
except Exception as error :
791
806
raise TypeError (f"{ self .name } interfaces cannot be resolved. { error } " )
@@ -833,8 +848,8 @@ class GraphQLInterfaceType(GraphQLNamedType):
833
848
def __init__ (
834
849
self ,
835
850
name : str ,
836
- fields : Optional [ Thunk [ GraphQLFieldMap ]] = None ,
837
- interfaces : Optional [Thunk [ Collection [ "GraphQLInterfaceType" ] ]] = None ,
851
+ fields : ThunkMapping [ GraphQLField ] ,
852
+ interfaces : Optional [ThunkCollection [ "GraphQLInterfaceType" ]] = None ,
838
853
resolve_type : Optional [GraphQLTypeResolver ] = None ,
839
854
description : Optional [str ] = None ,
840
855
extensions : Optional [Dict [str , Any ]] = None ,
@@ -881,15 +896,15 @@ def __copy__(self) -> "GraphQLInterfaceType": # pragma: no cover
881
896
def fields (self ) -> GraphQLFieldMap :
882
897
"""Get provided fields, wrapping them as GraphQLFields if needed."""
883
898
try :
884
- fields = resolve_thunk (self ._fields )
899
+ fields = resolve_thunk_mapping (self ._fields )
885
900
except Exception as error :
886
901
raise TypeError (f"{ self .name } fields cannot be resolved. { error } " )
887
- if not isinstance (fields , dict ) or not all (
902
+ if not isinstance (fields , Mapping ) or not all (
888
903
isinstance (key , str ) for key in fields
889
904
):
890
905
raise TypeError (
891
906
f"{ self .name } fields must be specified"
892
- " as a dict with field names as keys."
907
+ " as a mapping with field names as keys."
893
908
)
894
909
if not all (
895
910
isinstance (value , GraphQLField ) or is_output_type (value )
@@ -899,16 +914,18 @@ def fields(self) -> GraphQLFieldMap:
899
914
f"{ self .name } fields must be GraphQLField or output type objects."
900
915
)
901
916
return {
902
- name : value if isinstance (value , GraphQLField ) else GraphQLField (value )
917
+ name : value
918
+ if isinstance (value , GraphQLField )
919
+ else GraphQLField (value ) # type: ignore
903
920
for name , value in fields .items ()
904
921
}
905
922
906
923
@cached_property
907
924
def interfaces (self ) -> List ["GraphQLInterfaceType" ]:
908
925
"""Get provided interfaces."""
909
926
try :
910
- interfaces : Collection ["GraphQLInterfaceType" ] = resolve_thunk (
911
- self ._interfaces
927
+ interfaces : Collection ["GraphQLInterfaceType" ] = resolve_thunk_collection (
928
+ self ._interfaces # type: ignore
912
929
)
913
930
except Exception as error :
914
931
raise TypeError (f"{ self .name } interfaces cannot be resolved. { error } " )
@@ -959,7 +976,7 @@ def resolve_type(obj, _info, _type):
959
976
def __init__ (
960
977
self ,
961
978
name : str ,
962
- types : Thunk [ Collection [ GraphQLObjectType ] ],
979
+ types : ThunkCollection [ GraphQLObjectType ],
963
980
resolve_type : Optional [GraphQLTypeResolver ] = None ,
964
981
description : Optional [str ] = None ,
965
982
extensions : Optional [Dict [str , Any ]] = None ,
@@ -1002,7 +1019,7 @@ def __copy__(self) -> "GraphQLUnionType": # pragma: no cover
1002
1019
def types (self ) -> List [GraphQLObjectType ]:
1003
1020
"""Get provided types."""
1004
1021
try :
1005
- types : Collection [GraphQLObjectType ] = resolve_thunk (self ._types )
1022
+ types : Collection [GraphQLObjectType ] = resolve_thunk_collection (self ._types )
1006
1023
except Exception as error :
1007
1024
raise TypeError (f"{ self .name } types cannot be resolved. { error } " )
1008
1025
if types is None :
@@ -1068,7 +1085,7 @@ class RGBEnum(enum.Enum):
1068
1085
def __init__ (
1069
1086
self ,
1070
1087
name : str ,
1071
- values : Union [GraphQLEnumValueMap , Dict [str , Any ], Type [Enum ]],
1088
+ values : Union [GraphQLEnumValueMap , Mapping [str , Any ], Type [Enum ]],
1072
1089
description : Optional [str ] = None ,
1073
1090
extensions : Optional [Dict [str , Any ]] = None ,
1074
1091
ast_node : Optional [EnumTypeDefinitionNode ] = None ,
@@ -1084,15 +1101,15 @@ def __init__(
1084
1101
try : # check for enum
1085
1102
values = cast (Enum , values ).__members__ # type: ignore
1086
1103
except AttributeError :
1087
- if not isinstance (values , dict ) or not all (
1104
+ if not isinstance (values , Mapping ) or not all (
1088
1105
isinstance (name , str ) for name in values
1089
1106
):
1090
1107
try :
1091
1108
# noinspection PyTypeChecker
1092
1109
values = dict (values ) # type: ignore
1093
1110
except (TypeError , ValueError ):
1094
1111
raise TypeError (
1095
- f"{ name } values must be an Enum or a dict "
1112
+ f"{ name } values must be an Enum or a mapping "
1096
1113
" with value names as keys."
1097
1114
)
1098
1115
values = cast (Dict , values )
@@ -1298,7 +1315,7 @@ class GeoPoint(GraphQLInputObjectType):
1298
1315
def __init__ (
1299
1316
self ,
1300
1317
name : str ,
1301
- fields : Thunk [ GraphQLInputFieldMap ],
1318
+ fields : ThunkMapping [ "GraphQLInputField" ],
1302
1319
description : Optional [str ] = None ,
1303
1320
out_type : Optional [GraphQLInputFieldOutType ] = None ,
1304
1321
extensions : Optional [Dict [str , Any ]] = None ,
@@ -1354,15 +1371,15 @@ def __copy__(self) -> "GraphQLInputObjectType": # pragma: no cover
1354
1371
def fields (self ) -> GraphQLInputFieldMap :
1355
1372
"""Get provided fields, wrap them as GraphQLInputField if needed."""
1356
1373
try :
1357
- fields = resolve_thunk (self ._fields )
1374
+ fields = resolve_thunk_mapping (self ._fields )
1358
1375
except Exception as error :
1359
1376
raise TypeError (f"{ self .name } fields cannot be resolved. { error } " )
1360
- if not isinstance (fields , dict ) or not all (
1377
+ if not isinstance (fields , Mapping ) or not all (
1361
1378
isinstance (key , str ) for key in fields
1362
1379
):
1363
1380
raise TypeError (
1364
1381
f"{ self .name } fields must be specified"
1365
- " as a dict with field names as keys."
1382
+ " as a mapping with field names as keys."
1366
1383
)
1367
1384
if not all (
1368
1385
isinstance (value , GraphQLInputField ) or is_input_type (value )
@@ -1375,7 +1392,7 @@ def fields(self) -> GraphQLInputFieldMap:
1375
1392
return {
1376
1393
name : value
1377
1394
if isinstance (value , GraphQLInputField )
1378
- else GraphQLInputField (value )
1395
+ else GraphQLInputField (value ) # type: ignore
1379
1396
for name , value in fields .items ()
1380
1397
}
1381
1398
0 commit comments