From 04496e1eb648cb652d4d317f61ebd0d53ca4ac7e Mon Sep 17 00:00:00 2001 From: Erik Wrede Date: Sat, 13 Sep 2025 19:06:22 +0200 Subject: [PATCH 1/3] feat: show `@oneOf` in introspection query --- src/graphql/utilities/build_client_schema.py | 1 + src/graphql/utilities/get_introspection_query.py | 7 ++++--- src/graphql/utilities/introspection_from_schema.py | 2 ++ tests/utilities/test_get_introspection_query.py | 7 +++++++ 4 files changed, 14 insertions(+), 3 deletions(-) diff --git a/src/graphql/utilities/build_client_schema.py b/src/graphql/utilities/build_client_schema.py index 0e2cbd0e..f32f4b72 100644 --- a/src/graphql/utilities/build_client_schema.py +++ b/src/graphql/utilities/build_client_schema.py @@ -256,6 +256,7 @@ def build_input_object_def( fields=lambda: build_input_value_def_map( input_object_introspection["inputFields"] ), + is_one_of= input_object_introspection.get("isOneOf"), ) type_builders: dict[str, Callable[[IntrospectionType], GraphQLNamedType]] = { diff --git a/src/graphql/utilities/get_introspection_query.py b/src/graphql/utilities/get_introspection_query.py index adf038ac..cdd65c7f 100644 --- a/src/graphql/utilities/get_introspection_query.py +++ b/src/graphql/utilities/get_introspection_query.py @@ -17,7 +17,6 @@ except ImportError: # Python < 3.10 from typing_extensions import TypeAlias - __all__ = [ "IntrospectionDirective", "IntrospectionEnumType", @@ -44,6 +43,7 @@ def get_introspection_query( directive_is_repeatable: bool = False, schema_description: bool = False, input_value_deprecation: bool = False, + input_object_one_of: bool = False, ) -> str: """Get a query for introspection. @@ -55,6 +55,7 @@ def get_introspection_query( maybe_specified_by_url = "specifiedByURL" if specified_by_url else "" maybe_directive_is_repeatable = "isRepeatable" if directive_is_repeatable else "" maybe_schema_description = maybe_description if schema_description else "" + maybe_input_object_one_of = 'isOneOf' if input_object_one_of else ""; def input_deprecation(string: str) -> str | None: return string if input_value_deprecation else "" @@ -87,6 +88,7 @@ def input_deprecation(string: str) -> str | None: name {maybe_description} {maybe_specified_by_url} + {maybe_input_object_one_of} fields(includeDeprecated: true) {{ name {maybe_description} @@ -253,6 +255,7 @@ class IntrospectionEnumType(WithName): class IntrospectionInputObjectType(WithName): kind: Literal["input_object"] inputFields: list[IntrospectionInputValue] + isOneOf: bool IntrospectionType: TypeAlias = Union[ @@ -264,7 +267,6 @@ class IntrospectionInputObjectType(WithName): IntrospectionInputObjectType, ] - IntrospectionOutputType: TypeAlias = Union[ IntrospectionScalarType, IntrospectionObjectType, @@ -273,7 +275,6 @@ class IntrospectionInputObjectType(WithName): IntrospectionEnumType, ] - IntrospectionInputType: TypeAlias = Union[ IntrospectionScalarType, IntrospectionEnumType, IntrospectionInputObjectType ] diff --git a/src/graphql/utilities/introspection_from_schema.py b/src/graphql/utilities/introspection_from_schema.py index a0440a32..b2fb45ef 100644 --- a/src/graphql/utilities/introspection_from_schema.py +++ b/src/graphql/utilities/introspection_from_schema.py @@ -21,6 +21,7 @@ def introspection_from_schema( directive_is_repeatable: bool = True, schema_description: bool = True, input_value_deprecation: bool = True, + input_object_one_of: bool = True, ) -> IntrospectionQuery: """Build an IntrospectionQuery from a GraphQLSchema @@ -37,6 +38,7 @@ def introspection_from_schema( directive_is_repeatable, schema_description, input_value_deprecation, + input_object_one_of, ) ) diff --git a/tests/utilities/test_get_introspection_query.py b/tests/utilities/test_get_introspection_query.py index 348d2cbf..ce56db13 100644 --- a/tests/utilities/test_get_introspection_query.py +++ b/tests/utilities/test_get_introspection_query.py @@ -3,6 +3,8 @@ import re from typing import Pattern +from wheel.macosx_libfile import version_min_command_fields + from graphql.language import parse from graphql.utilities import build_schema, get_introspection_query from graphql.validation import validate @@ -80,6 +82,11 @@ def includes_deprecation_reason_field_on_input_values(): "deprecationReason", 2 ) + def includes_input_object_one_of_field(): + ExcpectIntrospectionQuery().to_not_match("isOneOf") + ExcpectIntrospectionQuery(input_object_one_of=True).to_match("isOneOf") + ExcpectIntrospectionQuery(input_object_one_of=False).to_not_match("isOneOf") + def includes_deprecated_input_field_and_args(): ExcpectIntrospectionQuery().to_match("includeDeprecated: true", 2) ExcpectIntrospectionQuery(input_value_deprecation=True).to_match( From b7699f2107b0780f428b01d5aed8578b4fe1bacf Mon Sep 17 00:00:00 2001 From: Erik Wrede Date: Sat, 13 Sep 2025 19:14:34 +0200 Subject: [PATCH 2/3] fix: remove slipped import --- tests/utilities/test_get_introspection_query.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/tests/utilities/test_get_introspection_query.py b/tests/utilities/test_get_introspection_query.py index ce56db13..df39b9e2 100644 --- a/tests/utilities/test_get_introspection_query.py +++ b/tests/utilities/test_get_introspection_query.py @@ -2,9 +2,6 @@ import re from typing import Pattern - -from wheel.macosx_libfile import version_min_command_fields - from graphql.language import parse from graphql.utilities import build_schema, get_introspection_query from graphql.validation import validate From 12abac78b327c83781df2491bdb8c1c05520ac1d Mon Sep 17 00:00:00 2001 From: Erik Wrede Date: Sat, 13 Sep 2025 19:16:27 +0200 Subject: [PATCH 3/3] chore: ruff --- src/graphql/utilities/build_client_schema.py | 2 +- src/graphql/utilities/get_introspection_query.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/graphql/utilities/build_client_schema.py b/src/graphql/utilities/build_client_schema.py index f32f4b72..b3d1ea65 100644 --- a/src/graphql/utilities/build_client_schema.py +++ b/src/graphql/utilities/build_client_schema.py @@ -256,7 +256,7 @@ def build_input_object_def( fields=lambda: build_input_value_def_map( input_object_introspection["inputFields"] ), - is_one_of= input_object_introspection.get("isOneOf"), + is_one_of=input_object_introspection.get("isOneOf"), ) type_builders: dict[str, Callable[[IntrospectionType], GraphQLNamedType]] = { diff --git a/src/graphql/utilities/get_introspection_query.py b/src/graphql/utilities/get_introspection_query.py index cdd65c7f..d24a61ff 100644 --- a/src/graphql/utilities/get_introspection_query.py +++ b/src/graphql/utilities/get_introspection_query.py @@ -55,7 +55,7 @@ def get_introspection_query( maybe_specified_by_url = "specifiedByURL" if specified_by_url else "" maybe_directive_is_repeatable = "isRepeatable" if directive_is_repeatable else "" maybe_schema_description = maybe_description if schema_description else "" - maybe_input_object_one_of = 'isOneOf' if input_object_one_of else ""; + maybe_input_object_one_of = "isOneOf" if input_object_one_of else "" def input_deprecation(string: str) -> str | None: return string if input_value_deprecation else ""