Skip to content

Commit 846d1a1

Browse files
committed
Move async methods into static methods
1 parent 6f51c70 commit 846d1a1

File tree

1 file changed

+94
-77
lines changed

1 file changed

+94
-77
lines changed

src/graphql/execution/execute.py

Lines changed: 94 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -299,11 +299,8 @@ def build_response(
299299
defined by the "Response" section of the GraphQL spec.
300300
"""
301301
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)
307304
data = cast(Optional[Dict[str, Any]], data)
308305
errors = self.errors
309306
if not errors:
@@ -350,14 +347,8 @@ def execute_operation(
350347
return None
351348
else:
352349
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)
361352
return result
362353

363354
def execute_fields_serially(
@@ -382,42 +373,17 @@ def execute_fields_serially(
382373
if result is Undefined:
383374
continue
384375
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
399378
)
400379
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(
411381
cast(Dict[str, Any], results), response_name, result
412382
)
413383
else:
414384
cast(Dict[str, Any], results)[response_name] = result
415385
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))
421387
return results
422388

423389
def execute_fields(
@@ -454,16 +420,7 @@ def execute_fields(
454420
# field, which is possibly a coroutine object. Return a coroutine object that
455421
# will yield this same map, but with any coroutines awaited in parallel and
456422
# 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)
467424

468425
def build_resolve_info(
469426
self,
@@ -532,36 +489,15 @@ def execute_field(
532489

533490
completed: AwaitableOrValue[Any]
534491
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+
)
550495

551496
completed = self.complete_value(
552497
return_type, field_nodes, info, path, result
553498
)
554499
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)
565501

566502
return completed
567503
except Exception as raw_error:
@@ -964,6 +900,87 @@ def collect_subfields(
964900
cache[key] = sub_field_nodes
965901
return sub_field_nodes
966902

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+
967984

968985
def execute(
969986
schema: GraphQLSchema,

0 commit comments

Comments
 (0)