@@ -299,11 +299,8 @@ def build_response(
299
299
defined by the "Response" section of the GraphQL spec.
300
300
"""
301
301
if self .is_awaitable (data ):
302
-
303
- async def build_response_async () -> ExecutionResult :
304
- return self .build_response (await data ) # type: ignore
305
-
306
- return build_response_async ()
302
+ data = cast (Awaitable , data )
303
+ return self .build_response_async (data )
307
304
data = cast (Optional [Dict [str , Any ]], data )
308
305
errors = self .errors
309
306
if not errors :
@@ -350,14 +347,8 @@ def execute_operation(
350
347
return None
351
348
else :
352
349
if self .is_awaitable (result ):
353
- # noinspection PyShadowingNames
354
- async def await_result () -> Any :
355
- try :
356
- return await result # type: ignore
357
- except GraphQLError as error :
358
- self .errors .append (error )
359
-
360
- return await_result ()
350
+ result = cast (Awaitable , result )
351
+ return self .await_result (result )
361
352
return result
362
353
363
354
def execute_fields_serially (
@@ -382,42 +373,17 @@ def execute_fields_serially(
382
373
if result is Undefined :
383
374
continue
384
375
if is_awaitable (results ):
385
- # noinspection PyShadowingNames
386
- async def await_and_set_result (
387
- results : Awaitable [Dict [str , Any ]],
388
- response_name : str ,
389
- result : AwaitableOrValue [Any ],
390
- ) -> Dict [str , Any ]:
391
- awaited_results = await results
392
- awaited_results [response_name ] = (
393
- await result if is_awaitable (result ) else result
394
- )
395
- return awaited_results
396
-
397
- results = await_and_set_result (
398
- cast (Awaitable , results ), response_name , result
376
+ results = ExecutionContext .await_and_set_result (
377
+ is_awaitable , cast (Awaitable , results ), response_name , result
399
378
)
400
379
elif is_awaitable (result ):
401
- # noinspection PyShadowingNames
402
- async def set_result (
403
- results : Dict [str , Any ],
404
- response_name : str ,
405
- result : Awaitable ,
406
- ) -> Dict [str , Any ]:
407
- results [response_name ] = await result
408
- return results
409
-
410
- results = set_result (
380
+ results = ExecutionContext .set_result (
411
381
cast (Dict [str , Any ], results ), response_name , result
412
382
)
413
383
else :
414
384
cast (Dict [str , Any ], results )[response_name ] = result
415
385
if is_awaitable (results ):
416
- # noinspection PyShadowingNames
417
- async def get_results () -> Any :
418
- return await cast (Awaitable , results )
419
-
420
- return get_results ()
386
+ return ExecutionContext .get_results (cast (Awaitable , results ))
421
387
return results
422
388
423
389
def execute_fields (
@@ -454,16 +420,7 @@ def execute_fields(
454
420
# field, which is possibly a coroutine object. Return a coroutine object that
455
421
# will yield this same map, but with any coroutines awaited in parallel and
456
422
# replaced with the values they yielded.
457
- async def get_results () -> Dict [str , Any ]:
458
- results .update (
459
- zip (
460
- awaitable_fields ,
461
- await gather (* (results [field ] for field in awaitable_fields )),
462
- )
463
- )
464
- return results
465
-
466
- return get_results ()
423
+ return ExecutionContext .get_results_map (awaitable_fields , results )
467
424
468
425
def build_resolve_info (
469
426
self ,
@@ -532,36 +489,15 @@ def execute_field(
532
489
533
490
completed : AwaitableOrValue [Any ]
534
491
if self .is_awaitable (result ):
535
- # noinspection PyShadowingNames
536
- async def await_result () -> Any :
537
- try :
538
- completed = self .complete_value (
539
- return_type , field_nodes , info , path , await result
540
- )
541
- if self .is_awaitable (completed ):
542
- return await completed
543
- return completed
544
- except Exception as raw_error :
545
- error = located_error (raw_error , field_nodes , path .as_list ())
546
- self .handle_field_error (error , return_type )
547
- return None
548
-
549
- return await_result ()
492
+ return self .await_field_result (
493
+ result , field_nodes , info , path , return_type
494
+ )
550
495
551
496
completed = self .complete_value (
552
497
return_type , field_nodes , info , path , result
553
498
)
554
499
if self .is_awaitable (completed ):
555
- # noinspection PyShadowingNames
556
- async def await_completed () -> Any :
557
- try :
558
- return await completed
559
- except Exception as raw_error :
560
- error = located_error (raw_error , field_nodes , path .as_list ())
561
- self .handle_field_error (error , return_type )
562
- return None
563
-
564
- return await_completed ()
500
+ return self .await_completed (completed , field_nodes , path , return_type )
565
501
566
502
return completed
567
503
except Exception as raw_error :
@@ -964,6 +900,87 @@ def collect_subfields(
964
900
cache [key ] = sub_field_nodes
965
901
return sub_field_nodes
966
902
903
+ # Async methods
904
+ async def build_response_async (
905
+ self , data : Awaitable [Optional [Dict [str , Any ]]]
906
+ ) -> ExecutionResult :
907
+ return self .build_response (await data ) # type: ignore
908
+
909
+ async def await_result (self , result : Awaitable [Dict [str , Any ]]) -> Optional [Any ]:
910
+ try :
911
+ return await result
912
+ except GraphQLError as error :
913
+ self .errors .append (error )
914
+ return None
915
+
916
+ @staticmethod
917
+ async def await_and_set_result (
918
+ is_awaitable : Callable [[Any ], bool ],
919
+ results : Awaitable [Dict [str , Any ]],
920
+ response_name : str ,
921
+ result : AwaitableOrValue [Any ],
922
+ ) -> Dict [str , Any ]:
923
+ awaited_results = await results
924
+ awaited_results [response_name ] = (
925
+ await result if is_awaitable (result ) else result
926
+ )
927
+ return awaited_results
928
+
929
+ @staticmethod
930
+ async def set_result (
931
+ results : Dict [str , Any ],
932
+ response_name : str ,
933
+ result : Awaitable ,
934
+ ) -> Dict [str , Any ]:
935
+ results [response_name ] = await result
936
+ return results
937
+
938
+ @staticmethod
939
+ async def get_results (results : Awaitable [Dict [str , Any ]]) -> Any :
940
+ return await results
941
+
942
+ @staticmethod
943
+ async def get_results_map (
944
+ awaitable_fields : List [str ], results : Dict [str , Any ]
945
+ ) -> Dict [str , Any ]:
946
+ results .update (
947
+ zip (
948
+ awaitable_fields ,
949
+ await gather (* (results [field ] for field in awaitable_fields )),
950
+ )
951
+ )
952
+ return results
953
+
954
+ async def await_field_result (
955
+ self ,
956
+ result : Any ,
957
+ field_nodes : List [FieldNode ],
958
+ info : GraphQLResolveInfo ,
959
+ path : Path ,
960
+ return_type ,
961
+ ) -> Any :
962
+ try :
963
+ completed = self .complete_value (
964
+ return_type , field_nodes , info , path , await result
965
+ )
966
+ if self .is_awaitable (completed ):
967
+ return await completed
968
+ return completed
969
+ except Exception as raw_error :
970
+ error = located_error (raw_error , field_nodes , path .as_list ())
971
+ self .handle_field_error (error , return_type )
972
+ return None
973
+
974
+ async def await_completed (
975
+ self , completed : Any , field_nodes : List [FieldNode ], path : Path , return_type
976
+ ) -> Any :
977
+ try :
978
+ return await completed
979
+ except Exception as raw_error :
980
+ error = located_error (raw_error , field_nodes , path .as_list ())
981
+ self .handle_field_error (error , return_type )
982
+ return None
983
+
967
984
968
985
def execute (
969
986
schema : GraphQLSchema ,
0 commit comments