Repository: graphql-python/graphene
Pull request #1420 (2022-05-03 11:56:13)

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.


Patch:
diff --git a/graphene/types/base64.py b/graphene/types/base64.py
index baedabe..69bb338 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 b2acbe7..94968f4 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 5d1a6c4..2a3c8d5 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 4bb5061..7e60de7 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 472f2d4..0bfcedf 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 c21eb16..4714a67 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)
 


Test patch:
diff --git a/graphene/tests/issues/test_1419.py b/graphene/tests/issues/test_1419.py
new file mode 100644
index 0000000..243645f
--- /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