diff --git a/CHANGELOG.md b/CHANGELOG.md index 8f96d96..6189d6c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +- `query`, `mutate` and `request_graphql` given a `gql` document raise a `TypeError` that says to pass the query string, instead of `Object of type DocumentNode is not JSON serializable`. + ## [v6.0.0] - 2026-10-28 - BREAKING: Drop support for Python 3.8 and 3.9, which are end of life. The minimum supported version is now Python 3.10. diff --git a/python_anvil/api.py b/python_anvil/api.py index 0916299..5897d57 100644 --- a/python_anvil/api.py +++ b/python_anvil/api.py @@ -321,6 +321,12 @@ def request_graphql( See the GraphQL reference for every query and mutation: https://www.useanvil.com/docs/api/graphql/reference/ """ + if not isinstance(query, str): + raise TypeError( + f"The query must be a string, not {type(query).__name__}. gql " + "documents aren't accepted since 6.0.0: pass the string you gave " + "gql(), or graphql.print_ast(document) for one built with its DSL." + ) given = ( json_lib.loads(variables) if isinstance(variables, (str, bytes)) @@ -370,7 +376,7 @@ def mutate( timeout: float | tuple[float, float] | None = None, ) -> dict[str, Any]: """Send a GraphQL mutation, as a string or a mutation class. The same as `request_graphql`.""" - mutation = query if isinstance(query, str) else query.get_mutation() + mutation = query.get_mutation() if isinstance(query, BaseQuery) else query return self.request_graphql(mutation, variables, timeout=timeout) def create_etch_packet( diff --git a/tests/test_compat.py b/tests/test_compat.py index 9d8f36e..96d74a6 100644 --- a/tests/test_compat.py +++ b/tests/test_compat.py @@ -8,6 +8,7 @@ from unittest import mock import pytest +from graphql import parse from python_anvil import Anvil from python_anvil.api_resources.mutations import CreateEtchPacket, ForgeSubmit @@ -91,6 +92,14 @@ def create_payload(self): == "mutation Mine($eid: String!) { mine(eid: $eid) { eid } }" ) + def they_refuse_a_gql_document_before_sending(anvil): + document = parse("{ currentUser { eid } }") + with mock.patch.object(anvil.client, "request") as request: + for method in (anvil.query, anvil.mutate, anvil.request_graphql): + with pytest.raises(TypeError, match=r"not DocumentNode.*print_ast"): + method(document) + request.assert_not_called() + def the_old_module_constants_are_the_mutations(): assert mutations.create_etch_packet.generate_mutation() == CREATE_ETCH_PACKET assert mutations.forge_submit.generate_mutation() == FORGE_SUBMIT