|
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