|
21 | 21 | DocumentNode,
|
22 | 22 | FieldNode,
|
23 | 23 | FragmentDefinitionNode,
|
24 |
| - FragmentSpreadNode, |
25 |
| - InlineFragmentNode, |
26 | 24 | OperationDefinitionNode,
|
27 | 25 | OperationType,
|
28 |
| - SelectionSetNode, |
29 | 26 | )
|
30 | 27 | from ..pyutils import (
|
31 | 28 | inspect,
|
|
37 | 34 | Undefined,
|
38 | 35 | )
|
39 | 36 | from ..utilities.get_operation_root_type import get_operation_root_type
|
40 |
| -from ..utilities.type_from_ast import type_from_ast |
41 | 37 | from ..type import (
|
42 | 38 | GraphQLAbstractType,
|
43 | 39 | GraphQLField,
|
44 |
| - GraphQLIncludeDirective, |
45 | 40 | GraphQLLeafType,
|
46 | 41 | GraphQLList,
|
47 | 42 | GraphQLNonNull,
|
48 | 43 | GraphQLObjectType,
|
49 | 44 | GraphQLOutputType,
|
50 | 45 | GraphQLSchema,
|
51 |
| - GraphQLSkipDirective, |
52 | 46 | GraphQLFieldResolver,
|
53 | 47 | GraphQLTypeResolver,
|
54 | 48 | GraphQLResolveInfo,
|
|
62 | 56 | is_non_null_type,
|
63 | 57 | is_object_type,
|
64 | 58 | )
|
| 59 | +from .collect_fields import collect_fields |
65 | 60 | from .middleware import MiddlewareManager
|
66 |
| -from .values import get_argument_values, get_directive_values, get_variable_values |
| 61 | +from .values import get_argument_values, get_variable_values |
67 | 62 |
|
68 | 63 | __all__ = [
|
69 | 64 | "assert_valid_execution_arguments",
|
@@ -328,7 +323,15 @@ def execute_operation(
|
328 | 323 | Implements the "Executing operations" section of the spec.
|
329 | 324 | """
|
330 | 325 | type_ = get_operation_root_type(self.schema, operation)
|
331 |
| - fields = self.collect_fields(type_, operation.selection_set, {}, set()) |
| 326 | + fields = collect_fields( |
| 327 | + self.schema, |
| 328 | + self.fragments, |
| 329 | + self.variable_values, |
| 330 | + type_, |
| 331 | + operation.selection_set, |
| 332 | + {}, |
| 333 | + set(), |
| 334 | + ) |
332 | 335 |
|
333 | 336 | path = None
|
334 | 337 |
|
@@ -462,96 +465,6 @@ async def get_results() -> Dict[str, Any]:
|
462 | 465 |
|
463 | 466 | return get_results()
|
464 | 467 |
|
465 |
| - def collect_fields( |
466 |
| - self, |
467 |
| - runtime_type: GraphQLObjectType, |
468 |
| - selection_set: SelectionSetNode, |
469 |
| - fields: Dict[str, List[FieldNode]], |
470 |
| - visited_fragment_names: Set[str], |
471 |
| - ) -> Dict[str, List[FieldNode]]: |
472 |
| - """Collect fields. |
473 |
| -
|
474 |
| - Given a selection_set, adds all of the fields in that selection to the passed in |
475 |
| - map of fields, and returns it at the end. |
476 |
| -
|
477 |
| - collect_fields requires the "runtime type" of an object. For a field which |
478 |
| - returns an Interface or Union type, the "runtime type" will be the actual |
479 |
| - Object type returned by that field. |
480 |
| -
|
481 |
| - For internal use only. |
482 |
| - """ |
483 |
| - for selection in selection_set.selections: |
484 |
| - if isinstance(selection, FieldNode): |
485 |
| - if not self.should_include_node(selection): |
486 |
| - continue |
487 |
| - name = get_field_entry_key(selection) |
488 |
| - fields.setdefault(name, []).append(selection) |
489 |
| - elif isinstance(selection, InlineFragmentNode): |
490 |
| - if not self.should_include_node( |
491 |
| - selection |
492 |
| - ) or not self.does_fragment_condition_match(selection, runtime_type): |
493 |
| - continue |
494 |
| - self.collect_fields( |
495 |
| - runtime_type, |
496 |
| - selection.selection_set, |
497 |
| - fields, |
498 |
| - visited_fragment_names, |
499 |
| - ) |
500 |
| - elif isinstance(selection, FragmentSpreadNode): # pragma: no cover else |
501 |
| - frag_name = selection.name.value |
502 |
| - if frag_name in visited_fragment_names or not self.should_include_node( |
503 |
| - selection |
504 |
| - ): |
505 |
| - continue |
506 |
| - visited_fragment_names.add(frag_name) |
507 |
| - fragment = self.fragments.get(frag_name) |
508 |
| - if not fragment or not self.does_fragment_condition_match( |
509 |
| - fragment, runtime_type |
510 |
| - ): |
511 |
| - continue |
512 |
| - self.collect_fields( |
513 |
| - runtime_type, fragment.selection_set, fields, visited_fragment_names |
514 |
| - ) |
515 |
| - return fields |
516 |
| - |
517 |
| - def should_include_node( |
518 |
| - self, node: Union[FragmentSpreadNode, FieldNode, InlineFragmentNode] |
519 |
| - ) -> bool: |
520 |
| - """Check if node should be included |
521 |
| -
|
522 |
| - Determines if a field should be included based on the @include and @skip |
523 |
| - directives, where @skip has higher precedence than @include. |
524 |
| - """ |
525 |
| - skip = get_directive_values(GraphQLSkipDirective, node, self.variable_values) |
526 |
| - if skip and skip["if"]: |
527 |
| - return False |
528 |
| - |
529 |
| - include = get_directive_values( |
530 |
| - GraphQLIncludeDirective, node, self.variable_values |
531 |
| - ) |
532 |
| - if include and not include["if"]: |
533 |
| - return False |
534 |
| - |
535 |
| - return True |
536 |
| - |
537 |
| - def does_fragment_condition_match( |
538 |
| - self, |
539 |
| - fragment: Union[FragmentDefinitionNode, InlineFragmentNode], |
540 |
| - type_: GraphQLObjectType, |
541 |
| - ) -> bool: |
542 |
| - """Determine if a fragment is applicable to the given type.""" |
543 |
| - type_condition_node = fragment.type_condition |
544 |
| - if not type_condition_node: |
545 |
| - return True |
546 |
| - conditional_type = type_from_ast(self.schema, type_condition_node) |
547 |
| - if conditional_type is type_: |
548 |
| - return True |
549 |
| - if is_abstract_type(conditional_type): |
550 |
| - return self.schema.is_sub_type( |
551 |
| - cast(GraphQLAbstractType, conditional_type), type_ |
552 |
| - ) |
553 |
| - return False |
554 |
| - |
555 | 468 | def build_resolve_info(
|
556 | 469 | self,
|
557 | 470 | field_def: GraphQLField,
|
@@ -1039,7 +952,10 @@ def collect_subfields(
|
1039 | 952 | for field_node in field_nodes:
|
1040 | 953 | selection_set = field_node.selection_set
|
1041 | 954 | if selection_set:
|
1042 |
| - sub_field_nodes = self.collect_fields( |
| 955 | + sub_field_nodes = collect_fields( |
| 956 | + self.schema, |
| 957 | + self.fragments, |
| 958 | + self.variable_values, |
1043 | 959 | return_type,
|
1044 | 960 | selection_set,
|
1045 | 961 | sub_field_nodes,
|
@@ -1216,11 +1132,6 @@ def get_field_def(
|
1216 | 1132 | return parent_type.fields.get(field_name)
|
1217 | 1133 |
|
1218 | 1134 |
|
1219 |
| -def get_field_entry_key(node: FieldNode) -> str: |
1220 |
| - """Implements the logic to compute the key of a given field's entry""" |
1221 |
| - return node.alias.value if node.alias else node.name.value |
1222 |
| - |
1223 |
| - |
1224 | 1135 | def invalid_return_type_error(
|
1225 | 1136 | return_type: GraphQLObjectType, result: Any, field_nodes: List[FieldNode]
|
1226 | 1137 | ) -> GraphQLError:
|
|
0 commit comments