Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit db05a21

Browse files
committed
simplify CollectFields for @defer and @stream
Replicates graphql/graphql-js@2aedf25
1 parent e7da373 commit db05a21

File tree

6 files changed

+369
-408
lines changed

6 files changed

+369
-408
lines changed

‎docs/conf.py

Lines changed: 77 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -138,79 +138,77 @@
138138
}
139139

140140
# ignore the following undocumented or internal references:
141-
ignore_references = set(
142-
[
143-
"GNT",
144-
"GT",
145-
"KT",
146-
"T",
147-
"VT",
148-
"TContext",
149-
"Enum",
150-
"traceback",
151-
"types.TracebackType",
152-
"TypeMap",
153-
"AwaitableOrValue",
154-
"DeferredFragmentRecord",
155-
"DeferUsage",
156-
"EnterLeaveVisitor",
157-
"ExperimentalIncrementalExecutionResults",
158-
"FieldGroup",
159-
"FormattedIncrementalResult",
160-
"FormattedPendingResult",
161-
"FormattedSourceLocation",
162-
"GraphQLAbstractType",
163-
"GraphQLCompositeType",
164-
"GraphQLEnumValueMap",
165-
"GraphQLErrorExtensions",
166-
"GraphQLFieldResolver",
167-
"GraphQLInputType",
168-
"GraphQLNullableType",
169-
"GraphQLOutputType",
170-
"GraphQLTypeResolver",
171-
"GroupedFieldSet",
172-
"IncrementalDataRecord",
173-
"IncrementalResult",
174-
"InitialResultRecord",
175-
"Middleware",
176-
"PendingResult",
177-
"StreamItemsRecord",
178-
"StreamRecord",
179-
"SubsequentDataRecord",
180-
"asyncio.events.AbstractEventLoop",
181-
"collections.abc.MutableMapping",
182-
"collections.abc.MutableSet",
183-
"enum.Enum",
184-
"graphql.execution.collect_fields.DeferUsage",
185-
"graphql.execution.collect_fields.CollectFieldsResult",
186-
"graphql.execution.collect_fields.FieldGroup",
187-
"graphql.execution.execute.StreamArguments",
188-
"graphql.execution.execute.StreamUsage",
189-
"graphql.execution.map_async_iterable.map_async_iterable",
190-
"graphql.execution.incremental_publisher.CompletedResult",
191-
"graphql.execution.incremental_publisher.DeferredFragmentRecord",
192-
"graphql.execution.incremental_publisher.DeferredGroupedFieldSetRecord",
193-
"graphql.execution.incremental_publisher.FormattedCompletedResult",
194-
"graphql.execution.incremental_publisher.FormattedPendingResult",
195-
"graphql.execution.incremental_publisher.IncrementalPublisher",
196-
"graphql.execution.incremental_publisher.InitialResultRecord",
197-
"graphql.execution.incremental_publisher.PendingResult",
198-
"graphql.execution.incremental_publisher.StreamItemsRecord",
199-
"graphql.execution.incremental_publisher.StreamRecord",
200-
"graphql.execution.Middleware",
201-
"graphql.language.lexer.EscapeSequence",
202-
"graphql.language.visitor.EnterLeaveVisitor",
203-
"graphql.pyutils.ref_map.K",
204-
"graphql.pyutils.ref_map.V",
205-
"graphql.type.definition.GT_co",
206-
"graphql.type.definition.GNT_co",
207-
"graphql.type.definition.TContext",
208-
"graphql.type.schema.InterfaceImplementations",
209-
"graphql.validation.validation_context.VariableUsage",
210-
"graphql.validation.rules.known_argument_names.KnownArgumentNamesOnDirectivesRule",
211-
"graphql.validation.rules.provided_required_arguments.ProvidedRequiredArgumentsOnDirectivesRule",
212-
]
213-
)
141+
ignore_references = {
142+
"GNT",
143+
"GT",
144+
"KT",
145+
"T",
146+
"VT",
147+
"TContext",
148+
"Enum",
149+
"traceback",
150+
"types.TracebackType",
151+
"TypeMap",
152+
"AwaitableOrValue",
153+
"DeferredFragmentRecord",
154+
"DeferUsage",
155+
"EnterLeaveVisitor",
156+
"ExperimentalIncrementalExecutionResults",
157+
"FieldGroup",
158+
"FormattedIncrementalResult",
159+
"FormattedPendingResult",
160+
"FormattedSourceLocation",
161+
"GraphQLAbstractType",
162+
"GraphQLCompositeType",
163+
"GraphQLEnumValueMap",
164+
"GraphQLErrorExtensions",
165+
"GraphQLFieldResolver",
166+
"GraphQLInputType",
167+
"GraphQLNullableType",
168+
"GraphQLOutputType",
169+
"GraphQLTypeResolver",
170+
"GroupedFieldSet",
171+
"IncrementalDataRecord",
172+
"IncrementalResult",
173+
"InitialResultRecord",
174+
"Middleware",
175+
"PendingResult",
176+
"StreamItemsRecord",
177+
"StreamRecord",
178+
"SubsequentDataRecord",
179+
"asyncio.events.AbstractEventLoop",
180+
"collections.abc.MutableMapping",
181+
"collections.abc.MutableSet",
182+
"enum.Enum",
183+
"graphql.execution.build_field_plan.FieldGroup",
184+
"graphql.execution.build_field_plan.FieldPlan",
185+
"graphql.execution.collect_fields.DeferUsage",
186+
"graphql.execution.execute.StreamArguments",
187+
"graphql.execution.execute.StreamUsage",
188+
"graphql.execution.map_async_iterable.map_async_iterable",
189+
"graphql.execution.incremental_publisher.CompletedResult",
190+
"graphql.execution.incremental_publisher.DeferredFragmentRecord",
191+
"graphql.execution.incremental_publisher.DeferredGroupedFieldSetRecord",
192+
"graphql.execution.incremental_publisher.FormattedCompletedResult",
193+
"graphql.execution.incremental_publisher.FormattedPendingResult",
194+
"graphql.execution.incremental_publisher.IncrementalPublisher",
195+
"graphql.execution.incremental_publisher.InitialResultRecord",
196+
"graphql.execution.incremental_publisher.PendingResult",
197+
"graphql.execution.incremental_publisher.StreamItemsRecord",
198+
"graphql.execution.incremental_publisher.StreamRecord",
199+
"graphql.execution.Middleware",
200+
"graphql.language.lexer.EscapeSequence",
201+
"graphql.language.visitor.EnterLeaveVisitor",
202+
"graphql.pyutils.ref_map.K",
203+
"graphql.pyutils.ref_map.V",
204+
"graphql.type.definition.GT_co",
205+
"graphql.type.definition.GNT_co",
206+
"graphql.type.definition.TContext",
207+
"graphql.type.schema.InterfaceImplementations",
208+
"graphql.validation.validation_context.VariableUsage",
209+
"graphql.validation.rules.known_argument_names.KnownArgumentNamesOnDirectivesRule",
210+
"graphql.validation.rules.provided_required_arguments.ProvidedRequiredArgumentsOnDirectivesRule",
211+
}
214212

215213
ignore_references.update(__builtins__.keys())
216214

@@ -228,10 +226,12 @@ def on_missing_reference(app, env, node, contnode):
228226
name = target.rsplit(".", 1)[-1]
229227
if name in ("GT", "GNT", "KT", "T", "VT"):
230228
return contnode
231-
if typ == "obj":
232-
if target.startswith("typing."):
233-
if name in ("Any", "Optional", "Union"):
234-
return contnode
229+
if (
230+
typ == "obj"
231+
and target.startswith("typing.")
232+
and name in ("Any", "Optional", "Union")
233+
):
234+
return contnode
235235
if typ != "class":
236236
return None
237237
if "." in target: # maybe too specific
Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
"""Build field plan"""
2+
3+
from __future__ import annotations
4+
5+
import sys
6+
from typing import TYPE_CHECKING, Dict, NamedTuple
7+
8+
from ..pyutils import RefMap, RefSet
9+
from .collect_fields import DeferUsage, FieldDetails
10+
11+
if TYPE_CHECKING:
12+
from ..language import FieldNode
13+
14+
try:
15+
from typing import TypeAlias
16+
except ImportError: # Python < 3.10
17+
from typing_extensions import TypeAlias
18+
19+
__all__ = [
20+
"DeferUsageSet",
21+
"FieldGroup",
22+
"FieldPlan",
23+
"GroupedFieldSet",
24+
"NewGroupedFieldSetDetails",
25+
"build_field_plan",
26+
]
27+
28+
29+
DeferUsageSet: TypeAlias = RefSet[DeferUsage]
30+
31+
32+
class FieldGroup(NamedTuple):
33+
"""A group of fields with defer usages."""
34+
35+
fields: list[FieldDetails]
36+
defer_usages: DeferUsageSet | None = None
37+
known_defer_usages: DeferUsageSet | None = None
38+
39+
def to_nodes(self) -> list[FieldNode]:
40+
"""Return the field nodes in this group."""
41+
return [field_details.node for field_details in self.fields]
42+
43+
44+
if sys.version_info < (3, 9):
45+
GroupedFieldSet: TypeAlias = Dict[str, FieldGroup]
46+
else: # Python >= 3.9
47+
GroupedFieldSet: TypeAlias = dict[str, FieldGroup]
48+
49+
50+
class NewGroupedFieldSetDetails(NamedTuple):
51+
"""Details of a new grouped field set."""
52+
53+
grouped_field_set: GroupedFieldSet
54+
should_initiate_defer: bool
55+
56+
57+
class FieldPlan(NamedTuple):
58+
"""A plan for executing fields."""
59+
60+
grouped_field_set: GroupedFieldSet
61+
new_grouped_field_set_details_map: RefMap[DeferUsageSet, NewGroupedFieldSetDetails]
62+
new_defer_usages: list[DeferUsage]
63+
64+
65+
def build_field_plan(
66+
fields: dict[str, list[FieldDetails]],
67+
parent_defer_usages: DeferUsageSet | None = None,
68+
known_defer_usages: DeferUsageSet | None = None,
69+
) -> FieldPlan:
70+
"""Build a plan for executing fields."""
71+
if parent_defer_usages is None:
72+
parent_defer_usages = RefSet()
73+
if known_defer_usages is None:
74+
known_defer_usages = RefSet()
75+
76+
new_defer_usages: RefSet[DeferUsage] = RefSet()
77+
new_known_defer_usages: RefSet[DeferUsage] = RefSet(known_defer_usages)
78+
79+
grouped_field_set: GroupedFieldSet = {}
80+
81+
new_grouped_field_set_details_map: RefMap[
82+
DeferUsageSet, NewGroupedFieldSetDetails
83+
] = RefMap()
84+
85+
map_: dict[str, tuple[DeferUsageSet, list[FieldDetails]]] = {}
86+
87+
for response_key, field_details_list in fields.items():
88+
defer_usage_set: RefSet[DeferUsage] = RefSet()
89+
in_original_result = False
90+
for field_details in field_details_list:
91+
defer_usage = field_details.defer_usage
92+
if defer_usage is None:
93+
in_original_result = True
94+
continue
95+
defer_usage_set.add(defer_usage)
96+
if defer_usage not in known_defer_usages:
97+
new_defer_usages.add(defer_usage)
98+
new_known_defer_usages.add(defer_usage)
99+
if in_original_result:
100+
defer_usage_set.clear()
101+
else:
102+
defer_usage_set -= {
103+
defer_usage
104+
for defer_usage in defer_usage_set
105+
if any(
106+
ancestor in defer_usage_set for ancestor in defer_usage.ancestors
107+
)
108+
}
109+
map_[response_key] = (defer_usage_set, field_details_list)
110+
111+
for response_key, [defer_usage_set, field_details_list] in map_.items():
112+
if defer_usage_set == parent_defer_usages:
113+
field_group = grouped_field_set.get(response_key)
114+
if field_group is None: # pragma: no cover else
115+
field_group = FieldGroup([], defer_usage_set, new_known_defer_usages)
116+
grouped_field_set[response_key] = field_group
117+
field_group.fields.extend(field_details_list)
118+
continue
119+
120+
for (
121+
new_grouped_field_set_defer_usage_set,
122+
new_grouped_field_set_details,
123+
) in new_grouped_field_set_details_map.items():
124+
if new_grouped_field_set_defer_usage_set == defer_usage_set:
125+
new_grouped_field_set = new_grouped_field_set_details.grouped_field_set
126+
break
127+
else:
128+
new_grouped_field_set = {}
129+
new_grouped_field_set_details = NewGroupedFieldSetDetails(
130+
new_grouped_field_set,
131+
any(
132+
defer_usage not in parent_defer_usages
133+
for defer_usage in defer_usage_set
134+
),
135+
)
136+
new_grouped_field_set_details_map[defer_usage_set] = (
137+
new_grouped_field_set_details
138+
)
139+
140+
field_group = new_grouped_field_set.get(response_key)
141+
if field_group is None: # pragma: no cover else
142+
field_group = FieldGroup([], defer_usage_set, new_known_defer_usages)
143+
new_grouped_field_set[response_key] = field_group
144+
field_group.fields.extend(field_details_list)
145+
146+
return FieldPlan(
147+
grouped_field_set, new_grouped_field_set_details_map, list(new_defer_usages)
148+
)

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /