Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow graphql-core 3.2.4 by retrofitting introspection commits #535

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 11 additions & 8 deletions gql/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@
GraphQLSchema,
IntrospectionQuery,
build_ast_schema,
get_introspection_query,
parse,
validate,
)
Expand All @@ -39,7 +38,7 @@
from .transport.exceptions import TransportClosed, TransportQueryError
from .transport.local_schema import LocalSchemaTransport
from .transport.transport import Transport
from .utilities import build_client_schema
from .utilities import build_client_schema, get_introspection_query_ast
from .utilities import parse_result as parse_result_fn
from .utilities import serialize_variable_values
from .utils import str_first_element
Expand Down Expand Up @@ -98,8 +97,8 @@ def __init__(
:param transport: The provided :ref:`transport <Transports>`.
:param fetch_schema_from_transport: Boolean to indicate that if we want to fetch
the schema from the transport using an introspection query.
:param introspection_args: arguments passed to the get_introspection_query
method of graphql-core.
:param introspection_args: arguments passed to the
:meth:`gql.utilities.get_introspection_query_ast` method.
:param execute_timeout: The maximum time in seconds for the execution of a
request before a TimeoutError is raised. Only used for async transports.
Passing None results in waiting forever for a response.
Expand Down Expand Up @@ -1289,8 +1288,10 @@ def fetch_schema(self) -> None:

Don't use this function and instead set the fetch_schema_from_transport
attribute to True"""
introspection_query = get_introspection_query(**self.client.introspection_args)
execution_result = self.transport.execute(parse(introspection_query))
introspection_query = get_introspection_query_ast(
**self.client.introspection_args
)
execution_result = self.transport.execute(introspection_query)

self.client._build_schema_from_introspection(execution_result)

Expand Down Expand Up @@ -1657,8 +1658,10 @@ async def fetch_schema(self) -> None:

Don't use this function and instead set the fetch_schema_from_transport
attribute to True"""
introspection_query = get_introspection_query(**self.client.introspection_args)
execution_result = await self.transport.execute(parse(introspection_query))
introspection_query = get_introspection_query_ast(
**self.client.introspection_args
)
execution_result = await self.transport.execute(introspection_query)

self.client._build_schema_from_introspection(execution_result)

Expand Down
20 changes: 17 additions & 3 deletions gql/utilities/get_introspection_query_ast.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ def get_introspection_query_ast(
specified_by_url: bool = False,
directive_is_repeatable: bool = False,
schema_description: bool = False,
input_value_deprecation: bool = False,
type_recursion_level: int = 7,
) -> DocumentNode:
"""Get a query for introspection as a document using the DSL module.
Expand Down Expand Up @@ -43,13 +44,20 @@ def get_introspection_query_ast(

directives = ds.__Schema.directives.select(ds.__Directive.name)

deprecated_expand = {}

if input_value_deprecation:
deprecated_expand = {
"includeDeprecated": True,
}

if descriptions:
directives.select(ds.__Directive.description)
if directive_is_repeatable:
directives.select(ds.__Directive.isRepeatable)
directives.select(
ds.__Directive.locations,
ds.__Directive.args.select(fragment_InputValue),
ds.__Directive.args(**deprecated_expand).select(fragment_InputValue),
)

schema.select(directives)
Expand All @@ -69,7 +77,7 @@ def get_introspection_query_ast(
fields.select(ds.__Field.description)

fields.select(
ds.__Field.args.select(fragment_InputValue),
ds.__Field.args(**deprecated_expand).select(fragment_InputValue),
ds.__Field.type.select(fragment_TypeRef),
ds.__Field.isDeprecated,
ds.__Field.deprecationReason,
Expand All @@ -89,7 +97,7 @@ def get_introspection_query_ast(

fragment_FullType.select(
fields,
ds.__Type.inputFields.select(fragment_InputValue),
ds.__Type.inputFields(**deprecated_expand).select(fragment_InputValue),
ds.__Type.interfaces.select(fragment_TypeRef),
enum_values,
ds.__Type.possibleTypes.select(fragment_TypeRef),
Expand All @@ -105,6 +113,12 @@ def get_introspection_query_ast(
ds.__InputValue.defaultValue,
)

if input_value_deprecation:
fragment_InputValue.select(
ds.__InputValue.isDeprecated,
ds.__InputValue.deprecationReason,
)

fragment_TypeRef.select(
ds.__Type.kind,
ds.__Type.name,
Expand Down
5 changes: 4 additions & 1 deletion gql/utilities/node_tree.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ def _node_tree_recursive(
results.append(" " * indent + f"{type(obj).__name__}")

try:
keys = obj.keys
keys = sorted(obj.keys)
except AttributeError:
# If the object has no keys attribute, print its repr and return.
results.append(" " * (indent + 1) + repr(obj))
Expand Down Expand Up @@ -70,6 +70,9 @@ def node_tree(

Useful to debug deep DocumentNode instances created by gql or dsl_gql.

NOTE: from gql version 3.6.0b4 the elements of each node are sorted to ignore
small changes in graphql-core

WARNING: the output of this method is not guaranteed and may change without notice.
"""

Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from setuptools import setup, find_packages

install_requires = [
"graphql-core>=3.2,<3.2.4",
"graphql-core>=3.2,<3.2.5",
"yarl>=1.6,<2.0",
"backoff>=1.11.1,<3.0",
"anyio>=3.0,<5",
Expand Down
112 changes: 66 additions & 46 deletions tests/starwars/test_dsl.py
Original file line number Diff line number Diff line change
Expand Up @@ -984,18 +984,36 @@ def test_get_introspection_query_ast(option):
specified_by_url=option,
directive_is_repeatable=option,
schema_description=option,
input_value_deprecation=option,
)
dsl_introspection_query = get_introspection_query_ast(
descriptions=option,
specified_by_url=option,
directive_is_repeatable=option,
schema_description=option,
input_value_deprecation=option,
)

assert print_ast(gql(introspection_query)) == print_ast(dsl_introspection_query)
assert node_tree(dsl_introspection_query) == node_tree(
gql(print_ast(dsl_introspection_query))
)
try:
assert print_ast(gql(introspection_query)) == print_ast(dsl_introspection_query)
assert node_tree(dsl_introspection_query) == node_tree(
gql(print_ast(dsl_introspection_query))
)
except AssertionError:

# From graphql-core version 3.3.0a7, there is two more type recursion levels
dsl_introspection_query = get_introspection_query_ast(
descriptions=option,
specified_by_url=option,
directive_is_repeatable=option,
schema_description=option,
input_value_deprecation=option,
type_recursion_level=9,
)
assert print_ast(gql(introspection_query)) == print_ast(dsl_introspection_query)
assert node_tree(dsl_introspection_query) == node_tree(
gql(print_ast(dsl_introspection_query))
)


def test_typename_aliased(ds):
Expand Down Expand Up @@ -1028,11 +1046,10 @@ def test_node_tree_with_loc(ds):

node_tree_result = """
DocumentNode
loc:
Location
<Location 0:43>
definitions:
OperationDefinitionNode
directives:
empty tuple
loc:
Location
<Location 0:43>
Expand All @@ -1043,33 +1060,31 @@ def test_node_tree_with_loc(ds):
<Location 6:17>
value:
'GetHeroName'
directives:
empty tuple
variable_definitions:
empty tuple
operation:
<OperationType.QUERY: 'query'>
selection_set:
SelectionSetNode
loc:
Location
<Location 18:43>
selections:
FieldNode
alias:
None
arguments:
empty tuple
directives:
empty tuple
loc:
Location
<Location 22:41>
directives:
empty tuple
alias:
None
name:
NameNode
loc:
Location
<Location 22:26>
value:
'hero'
arguments:
empty tuple
nullability_assertion:
None
selection_set:
Expand All @@ -1079,37 +1094,39 @@ def test_node_tree_with_loc(ds):
<Location 27:41>
selections:
FieldNode
alias:
None
arguments:
empty tuple
directives:
empty tuple
loc:
Location
<Location 33:37>
directives:
empty tuple
alias:
None
name:
NameNode
loc:
Location
<Location 33:37>
value:
'name'
arguments:
empty tuple
nullability_assertion:
None
selection_set:
None
operation:
<OperationType.QUERY: 'query'>
variable_definitions:
empty tuple
loc:
Location
<Location 0:43>
""".strip()

node_tree_result_stable = """
DocumentNode
loc:
Location
<Location 0:43>
definitions:
OperationDefinitionNode
directives:
empty tuple
loc:
Location
<Location 0:43>
Expand All @@ -1120,62 +1137,65 @@ def test_node_tree_with_loc(ds):
<Location 6:17>
value:
'GetHeroName'
directives:
empty tuple
variable_definitions:
empty tuple
operation:
<OperationType.QUERY: 'query'>
selection_set:
SelectionSetNode
loc:
Location
<Location 18:43>
selections:
FieldNode
alias:
None
arguments:
empty tuple
directives:
empty tuple
loc:
Location
<Location 22:41>
directives:
empty tuple
alias:
None
name:
NameNode
loc:
Location
<Location 22:26>
value:
'hero'
arguments:
empty tuple
selection_set:
SelectionSetNode
loc:
Location
<Location 27:41>
selections:
FieldNode
alias:
None
arguments:
empty tuple
directives:
empty tuple
loc:
Location
<Location 33:37>
directives:
empty tuple
alias:
None
name:
NameNode
loc:
Location
<Location 33:37>
value:
'name'
arguments:
empty tuple
selection_set:
None
operation:
<OperationType.QUERY: 'query'>
variable_definitions:
empty tuple
loc:
Location
<Location 0:43>
""".strip()

print(node_tree(document, ignore_loc=False))

try:
assert node_tree(document, ignore_loc=False) == node_tree_result
except AssertionError:
Expand Down
Loading