Skip to content

Commit 248e100

Browse files
committed
separate_operations: simplify algorithm
Replicates graphql/graphql-js@e2a6f23
1 parent fc89fa4 commit 248e100

File tree

1 file changed

+22
-28
lines changed

1 file changed

+22
-28
lines changed

src/graphql/utilities/separate_operations.py

Lines changed: 22 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
from collections import defaultdict
2-
from typing import Dict, List, Set
2+
from typing import DefaultDict, Dict, List, Set
33

44
from ..language import (
55
DocumentNode,
6-
ExecutableDefinitionNode,
76
FragmentDefinitionNode,
87
OperationDefinitionNode,
98
Visitor,
@@ -13,7 +12,7 @@
1312
__all__ = ["separate_operations"]
1413

1514

16-
DepGraph = Dict[str, Set[str]]
15+
DepGraph = DefaultDict[str, Set[str]]
1716

1817

1918
def separate_operations(document_ast: DocumentNode) -> Dict[str, DocumentNode]:
@@ -23,13 +22,10 @@ def separate_operations(document_ast: DocumentNode) -> Dict[str, DocumentNode]:
2322
fragments and returns a collection of AST documents each of which contains a single
2423
operation as well the fragment definitions it refers to.
2524
"""
26-
2725
# Populate metadata and build a dependency graph.
2826
visitor = SeparateOperations()
2927
visit(document_ast, visitor)
3028
operations = visitor.operations
31-
fragments = visitor.fragments
32-
positions = visitor.positions
3329
dep_graph = visitor.dep_graph
3430

3531
# For each operation, produce a new synthesized AST which includes only what is
@@ -40,44 +36,42 @@ def separate_operations(document_ast: DocumentNode) -> Dict[str, DocumentNode]:
4036
dependencies: Set[str] = set()
4137
collect_transitive_dependencies(dependencies, dep_graph, operation_name)
4238

43-
# The list of definition nodes to be included for this operation, sorted to
44-
# retain the same order as the original document.
45-
definitions: List[ExecutableDefinitionNode] = [operation]
46-
for name in dependencies:
47-
definitions.append(fragments[name])
48-
definitions.sort(key=lambda n: positions.get(n, 0))
49-
50-
separated_document_asts[operation_name] = DocumentNode(definitions=definitions)
39+
# The list of definition nodes to be included for this operation, sorted
40+
# to retain the same order as the original document.
41+
separated_document_asts[operation_name] = DocumentNode(
42+
definitions=[
43+
node
44+
for node in document_ast.definitions
45+
if node is operation
46+
or (
47+
isinstance(node, FragmentDefinitionNode)
48+
and node.name.value in dependencies
49+
)
50+
]
51+
)
5152

5253
return separated_document_asts
5354

5455

55-
# noinspection PyAttributeOutsideInit
5656
class SeparateOperations(Visitor):
57+
operations: List[OperationDefinitionNode]
58+
dep_graph: DepGraph
59+
from_name: str
60+
5761
def __init__(self):
5862
super().__init__()
59-
self.operations: List[OperationDefinitionNode] = []
60-
self.fragments: Dict[str, FragmentDefinitionNode] = {}
61-
self.positions: Dict[ExecutableDefinitionNode, int] = {}
62-
self.dep_graph: DepGraph = defaultdict(set)
63-
self.from_name: str
64-
self.idx = 0
63+
self.operations = []
64+
self.dep_graph = defaultdict(set)
6565

6666
def enter_operation_definition(self, node, *_args):
6767
self.from_name = op_name(node)
6868
self.operations.append(node)
69-
self.positions[node] = self.idx
70-
self.idx += 1
7169

7270
def enter_fragment_definition(self, node, *_args):
7371
self.from_name = node.name.value
74-
self.fragments[self.from_name] = node
75-
self.positions[node] = self.idx
76-
self.idx += 1
7772

7873
def enter_fragment_spread(self, node, *_args):
79-
to_name = node.name.value
80-
self.dep_graph[self.from_name].add(to_name)
74+
self.dep_graph[self.from_name].add(node.name.value)
8175

8276

8377
def op_name(operation: OperationDefinitionNode) -> str:

0 commit comments

Comments
 (0)