Field of an object type.
| 663 | |
| 664 | |
| 665 | class _ObjectField: |
| 666 | """Field of an object type.""" |
| 667 | |
| 668 | def __init__( |
| 669 | self, |
| 670 | ctx: Context, |
| 671 | name: str, |
| 672 | field: GraphQLField, |
| 673 | parent: GraphQLObjectType, |
| 674 | ) -> None: |
| 675 | self.ctx = ctx |
| 676 | self.graphql_name = name |
| 677 | self.graphql = field |
| 678 | |
| 679 | self.name = format_name(name) |
| 680 | self.named_type = get_named_type(field.type) |
| 681 | self.parent_name = get_named_type(parent).name |
| 682 | |
| 683 | self.required_args = [] |
| 684 | self.default_args = [] |
| 685 | for args in field.args.items(): |
| 686 | arg = _InputField(ctx, *args, parent=self) |
| 687 | (self.default_args if arg.has_default else self.required_args).append(arg) |
| 688 | self.args = self.required_args + self.default_args |
| 689 | self.description = field.description |
| 690 | |
| 691 | self.is_leaf = is_output_leaf_type(field.type) |
| 692 | self.is_list = is_list_of_objects_type(field.type) |
| 693 | self.is_exec = self.is_leaf or self.is_list |
| 694 | self.is_void = self.is_leaf and self.named_type.name == "Void" |
| 695 | |
| 696 | # Read @expectedType directive from the field's AST node. |
| 697 | self.expected_type = expected_type_name(ctx.schema, field.ast_node) |
| 698 | legacy_output_id_type = self.expected_type |
| 699 | if ( |
| 700 | legacy_output_id_type is None |
| 701 | and ctx.legacy_sdk_compat |
| 702 | and name == "id" |
| 703 | and self.parent_name != "Node" |
| 704 | ): |
| 705 | legacy_output_id_type = self.parent_name |
| 706 | self.type = format_output_type( |
| 707 | field.type, |
| 708 | legacy_output_id_type, |
| 709 | ctx.legacy_sdk_compat, |
| 710 | ) |
| 711 | |
| 712 | # Any field in the API that returns an ID for its parent object should |
| 713 | # return the binding for the object instead in the SDK to allow continued |
| 714 | # chaining, except if it's called "id". |
| 715 | # |
| 716 | # For example, the API `Service { start: ID! @expectedType(name: "Service") }` |
| 717 | # should produce the following binding signature: |
| 718 | # >>> class Service: |
| 719 | # ... async def start(self) -> Self: ... |
| 720 | # |
| 721 | self.convert_id = False |
| 722 | if ( |
no outgoing calls