Skip to content

Commit b481e71

Browse files
committed
polish: introduce execute_execution_plan to conform to spec algo
Replicates graphql/graphql-js@6731c76
1 parent 64b862c commit b481e71

1 file changed

Lines changed: 67 additions & 68 deletions

File tree

‎src/graphql/execution/execute.py‎

Lines changed: 67 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -372,37 +372,21 @@ def execute_operation(
372372
collected_fields = collect_fields(
373373
schema, self.fragments, self.variable_values, root_type, operation
374374
)
375+
375376
grouped_field_set, new_defer_usages = collected_fields
376377

377-
if new_defer_usages:
378-
execution_plan = build_execution_plan(grouped_field_set)
379-
grouped_field_set = execution_plan.grouped_field_set
380-
new_grouped_field_sets = execution_plan.new_grouped_field_sets
381-
new_defer_map = add_new_deferred_fragments(new_defer_usages, RefMap())
382-
graphql_wrapped_result = self.execute_root_grouped_field_set(
383-
operation.operation,
378+
graphql_wrapped_result = (
379+
self.execute_execution_plan(
384380
root_type,
385381
root_value,
386-
grouped_field_set,
387-
new_defer_map,
382+
new_defer_usages,
383+
build_execution_plan(grouped_field_set),
388384
)
389-
if new_grouped_field_sets:
390-
new_pending_execution_groups = self.collect_execution_groups(
391-
root_type,
392-
root_value,
393-
None,
394-
None,
395-
new_grouped_field_sets,
396-
new_defer_map,
397-
)
398-
graphql_wrapped_result = self.with_new_execution_groups(
399-
graphql_wrapped_result, new_pending_execution_groups
400-
)
401-
402-
else:
403-
graphql_wrapped_result = self.execute_root_grouped_field_set(
385+
if new_defer_usages
386+
else self.execute_root_grouped_field_set(
404387
operation.operation, root_type, root_value, grouped_field_set, None
405388
)
389+
)
406390

407391
if self.is_awaitable(graphql_wrapped_result):
408392

@@ -426,6 +410,45 @@ async def await_result() -> (
426410

427411
return self.build_data_response(resolved.result, resolved.increments)
428412

413+
def execute_execution_plan(
414+
self,
415+
return_type: GraphQLObjectType,
416+
source_value: Any,
417+
new_defer_usages: list[DeferUsage],
418+
execution_plan: ExecutionPlan,
419+
path: Path | None = None,
420+
incremental_context: IncrementalContext | None = None,
421+
defer_map: RefMap[DeferUsage, DeferredFragmentRecord] | None = None,
422+
) -> AwaitableOrValue[GraphQLWrappedResult[dict[str, Any]]]:
423+
"""Execute an execution plan."""
424+
new_defer_map = get_new_defer_map(new_defer_usages, defer_map, path)
425+
426+
grouped_field_set, new_grouped_field_sets = execution_plan
427+
428+
graphql_wrapped_result = self.execute_fields(
429+
return_type,
430+
source_value,
431+
path,
432+
grouped_field_set,
433+
incremental_context,
434+
new_defer_map,
435+
)
436+
437+
if new_grouped_field_sets:
438+
new_pending_execution_groups = self.collect_execution_groups(
439+
return_type,
440+
source_value,
441+
path,
442+
incremental_context.defer_usage_set if incremental_context else None,
443+
new_grouped_field_sets,
444+
new_defer_map,
445+
)
446+
return self.with_new_execution_groups(
447+
graphql_wrapped_result, new_pending_execution_groups
448+
)
449+
450+
return graphql_wrapped_result
451+
429452
def execute_root_grouped_field_set(
430453
self,
431454
operation: OperationType,
@@ -1479,46 +1502,27 @@ def collect_and_execute_subfields(
14791502
"""Collect sub-fields to execute to complete this value."""
14801503
collected_subfields = self.collect_subfields(return_type, field_group)
14811504
grouped_field_set, new_defer_usages = collected_subfields
1482-
if defer_map is None and not new_defer_usages:
1483-
return self.execute_fields(
1505+
1506+
return (
1507+
self.execute_fields(
14841508
return_type, result, path, grouped_field_set, incremental_context, None
14851509
)
1486-
sub_execution_plan = self.build_sub_execution_plan(
1487-
grouped_field_set,
1488-
incremental_context.defer_usage_set if incremental_context else None,
1489-
)
1490-
1491-
grouped_field_set, new_grouped_field_sets = sub_execution_plan
1492-
1493-
new_defer_map = add_new_deferred_fragments(
1494-
new_defer_usages,
1495-
RefMap(defer_map.items()) if defer_map else RefMap(),
1496-
path,
1497-
)
1498-
1499-
sub_fields = self.execute_fields(
1500-
return_type,
1501-
result,
1502-
path,
1503-
grouped_field_set,
1504-
incremental_context,
1505-
new_defer_map,
1506-
)
1507-
1508-
if new_grouped_field_sets:
1509-
new_deferred_grouped_field_set_records = self.collect_execution_groups(
1510+
if defer_map is None and not new_defer_usages
1511+
else self.execute_execution_plan(
15101512
return_type,
15111513
result,
1514+
new_defer_usages,
1515+
self.build_sub_execution_plan(
1516+
grouped_field_set,
1517+
incremental_context.defer_usage_set
1518+
if incremental_context
1519+
else None,
1520+
),
15121521
path,
1513-
incremental_context.defer_usage_set if incremental_context else None,
1514-
new_grouped_field_sets,
1515-
new_defer_map,
1516-
)
1517-
return self.with_new_execution_groups(
1518-
sub_fields, new_deferred_grouped_field_set_records
1522+
incremental_context,
1523+
defer_map,
15191524
)
1520-
1521-
return sub_fields
1525+
)
15221526

15231527
def collect_subfields(
15241528
self, return_type: GraphQLObjectType, field_group: FieldGroup
@@ -2289,27 +2293,22 @@ def deferred_fragment_record_from_defer_usage(
22892293
return defer_map[defer_usage]
22902294

22912295

2292-
def add_new_deferred_fragments(
2296+
def get_new_defer_map(
22932297
new_defer_usages: Sequence[DeferUsage],
2294-
new_defer_map: RefMap[DeferUsage, DeferredFragmentRecord],
2298+
defer_map: RefMap[DeferUsage, DeferredFragmentRecord] | None,
22952299
path: Path | None = None,
22962300
) -> RefMap[DeferUsage, DeferredFragmentRecord]:
2297-
"""Add new deferred fragments to the defer map.
2301+
"""Get the new defer map.
22982302
22992303
Instantiates new DeferredFragmentRecords for the given path within an
23002304
incremental data record, returning an updated map of DeferUsage
23012305
objects to DeferredFragmentRecords.
23022306
23032307
Note: As defer directives may be used with operations returning lists,
23042308
a DeferUsage object may correspond to many DeferredFragmentRecords.
2305-
2306-
DeferredFragmentRecord creation includes the following steps:
2307-
1. The new DeferredFragmentRecord is instantiated at the given path.
2308-
2. The parent result record is calculated from the given incremental data record.
2309-
3. The IncrementalPublisher is notified that a new DeferredFragmentRecord
2310-
with the calculated parent has been added; the record will be released only
2311-
after the parent has completed.
23122309
"""
2310+
new_defer_map = RefMap(None if defer_map is None else defer_map.items())
2311+
23132312
# For each new DeferUsage object:
23142313
for new_defer_usage in new_defer_usages:
23152314
parent_defer_usage = new_defer_usage.parent_defer_usage

0 commit comments

Comments
 (0)