From 181d9f76da858e1f7aff27f428e9d9499a0e0063 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Birrer?= Date: Tue, 3 May 2022 13:51:14 +0200 Subject: [PATCH] fix: add default param _variables to parse_literal #1419 This is to match the `graphql-core` API. If it's not respected the `parse_literal` method will produce an error event though dealing with a valid value. --- graphene/tests/issues/test_1419.py | 53 ++++++++++++++++++++++++++++++ graphene/types/base64.py | 2 +- graphene/types/decimal.py | 2 +- graphene/types/generic.py | 2 +- graphene/types/json.py | 2 +- graphene/types/scalars.py | 12 +++---- graphene/types/uuid.py | 2 +- 7 files changed, 64 insertions(+), 11 deletions(-) create mode 100644 graphene/tests/issues/test_1419.py diff --git a/graphene/tests/issues/test_1419.py b/graphene/tests/issues/test_1419.py new file mode 100644 index 00000000..243645fa --- /dev/null +++ b/graphene/tests/issues/test_1419.py @@ -0,0 +1,53 @@ +import pytest + +from ...types.base64 import Base64 +from ...types.datetime import Date, DateTime +from ...types.decimal import Decimal +from ...types.generic import GenericScalar +from ...types.json import JSONString +from ...types.objecttype import ObjectType +from ...types.scalars import ID, BigInt, Boolean, Float, Int, String +from ...types.schema import Schema +from ...types.uuid import UUID + + +@pytest.mark.parametrize( + "input_type,input_value", + [ + (Date, '"2022-02-02"'), + (GenericScalar, '"foo"'), + (Int, "1"), + (BigInt, "12345678901234567890"), + (Float, "1.1"), + (String, '"foo"'), + (Boolean, "true"), + (ID, "1"), + (DateTime, '"2022-02-02T11:11:11"'), + (UUID, '"cbebbc62-758e-4f75-a890-bc73b5017d81"'), + (Decimal, "1.1"), + (JSONString, '{key:"foo",value:"bar"}'), + (Base64, '"Q2hlbG8gd29ycmxkCg=="'), + ], +) +def test_parse_literal_with_variables(input_type, input_value): + # input_b needs to be evaluated as literal while the variable dict for + # input_a is passed along. + + class Query(ObjectType): + generic = GenericScalar(input_a=GenericScalar(), input_b=input_type()) + + def resolve_generic(self, info, input_a=None, input_b=None): + return input + + schema = Schema(query=Query) + + query = f""" + query Test($a: GenericScalar){{ + generic(inputA: $a, inputB: {input_value}) + }} + """ + result = schema.execute( + query, + variables={"a": "bar"}, + ) + assert not result.errors diff --git a/graphene/types/base64.py b/graphene/types/base64.py index baedabeb..69bb3380 100644 --- a/graphene/types/base64.py +++ b/graphene/types/base64.py @@ -22,7 +22,7 @@ class Base64(Scalar): return b64encode(value).decode("utf-8") @classmethod - def parse_literal(cls, node): + def parse_literal(cls, node, _variables=None): if not isinstance(node, StringValueNode): raise GraphQLError( f"Base64 cannot represent non-string value: {print_ast(node)}" diff --git a/graphene/types/decimal.py b/graphene/types/decimal.py index b2acbe7e..94968f49 100644 --- a/graphene/types/decimal.py +++ b/graphene/types/decimal.py @@ -22,7 +22,7 @@ class Decimal(Scalar): return str(dec) @classmethod - def parse_literal(cls, node): + def parse_literal(cls, node, _variables=None): if isinstance(node, (StringValueNode, IntValueNode)): return cls.parse_value(node.value) diff --git a/graphene/types/generic.py b/graphene/types/generic.py index 5d1a6c4b..2a3c8d52 100644 --- a/graphene/types/generic.py +++ b/graphene/types/generic.py @@ -29,7 +29,7 @@ class GenericScalar(Scalar): parse_value = identity @staticmethod - def parse_literal(ast): + def parse_literal(ast, _variables=None): if isinstance(ast, (StringValueNode, BooleanValueNode)): return ast.value elif isinstance(ast, IntValueNode): diff --git a/graphene/types/json.py b/graphene/types/json.py index 4bb5061c..7e60de7e 100644 --- a/graphene/types/json.py +++ b/graphene/types/json.py @@ -20,7 +20,7 @@ class JSONString(Scalar): return json.dumps(dt) @staticmethod - def parse_literal(node): + def parse_literal(node, _variables=None): if isinstance(node, StringValueNode): return json.loads(node.value) diff --git a/graphene/types/scalars.py b/graphene/types/scalars.py index 472f2d41..0bfcedfb 100644 --- a/graphene/types/scalars.py +++ b/graphene/types/scalars.py @@ -75,7 +75,7 @@ class Int(Scalar): parse_value = coerce_int @staticmethod - def parse_literal(ast): + def parse_literal(ast, _variables=None): if isinstance(ast, IntValueNode): num = int(ast.value) if MIN_INT <= num <= MAX_INT: @@ -104,7 +104,7 @@ class BigInt(Scalar): parse_value = coerce_int @staticmethod - def parse_literal(ast): + def parse_literal(ast, _variables=None): if isinstance(ast, IntValueNode): return int(ast.value) @@ -128,7 +128,7 @@ class Float(Scalar): parse_value = coerce_float @staticmethod - def parse_literal(ast): + def parse_literal(ast, _variables=None): if isinstance(ast, (FloatValueNode, IntValueNode)): return float(ast.value) @@ -150,7 +150,7 @@ class String(Scalar): parse_value = coerce_string @staticmethod - def parse_literal(ast): + def parse_literal(ast, _variables=None): if isinstance(ast, StringValueNode): return ast.value @@ -164,7 +164,7 @@ class Boolean(Scalar): parse_value = bool @staticmethod - def parse_literal(ast): + def parse_literal(ast, _variables=None): if isinstance(ast, BooleanValueNode): return ast.value @@ -182,6 +182,6 @@ class ID(Scalar): parse_value = str @staticmethod - def parse_literal(ast): + def parse_literal(ast, _variables=None): if isinstance(ast, (StringValueNode, IntValueNode)): return ast.value diff --git a/graphene/types/uuid.py b/graphene/types/uuid.py index c21eb165..4714a67f 100644 --- a/graphene/types/uuid.py +++ b/graphene/types/uuid.py @@ -21,7 +21,7 @@ class UUID(Scalar): return str(uuid) @staticmethod - def parse_literal(node): + def parse_literal(node, _variables=None): if isinstance(node, StringValueNode): return _UUID(node.value)