From d3305f6056d7de38e736ab26f2f36b9ea3b8491c Mon Sep 17 00:00:00 2001 From: Markus Padourek Date: Fri, 21 Oct 2016 09:34:06 +0100 Subject: [PATCH 1/5] Make scalar get_type an instance method. Given the current way of how Scalars are mostly being created in the schema, e.g. `graphene.Boolean(description='Some boolean')` and then how they get 'magically' turned into a `Field` using `self.get_type()` it makes sense to make this an Instance method rather than a classmethod. This allows e.g. to set attributes on the instance that will always be accessible, as they are being returned by `get_type`. --- graphene/types/scalars.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/graphene/types/scalars.py b/graphene/types/scalars.py index d6060d33..a9b5b7af 100644 --- a/graphene/types/scalars.py +++ b/graphene/types/scalars.py @@ -41,9 +41,8 @@ class Scalar(six.with_metaclass(ScalarTypeMeta, UnmountedType)): parse_value = None parse_literal = None - @classmethod - def get_type(cls): - return cls + def get_type(self): + return self # As per the GraphQL Spec, Integers are only treated as valid when a valid # 32-bit signed integer, providing the broadest support across platforms. From 014769294b1be00e81ddadaa920d2dcc8c5e0c0e Mon Sep 17 00:00:00 2001 From: Markus Padourek Date: Fri, 21 Oct 2016 09:45:55 +0100 Subject: [PATCH 2/5] Override instance get_type on scalar instantiation for backwards-compativbility --- graphene/types/scalars.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/graphene/types/scalars.py b/graphene/types/scalars.py index a9b5b7af..d30d92b4 100644 --- a/graphene/types/scalars.py +++ b/graphene/types/scalars.py @@ -37,10 +37,16 @@ class Scalar(six.with_metaclass(ScalarTypeMeta, UnmountedType)): used to parse input from ast or variables and to ensure validity. ''' + def __init__(self): + def get_type(self): + return self + self.get_type = types.MethodType(get_type, self) + serialize = None parse_value = None parse_literal = None + @classmethod def get_type(self): return self From 45b3ba55d76000614bb9a0bdaaff46e72cb56384 Mon Sep 17 00:00:00 2001 From: Markus Padourek Date: Fri, 21 Oct 2016 10:18:26 +0100 Subject: [PATCH 3/5] Fix linting. --- graphene/types/scalars.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/graphene/types/scalars.py b/graphene/types/scalars.py index d30d92b4..c917949e 100644 --- a/graphene/types/scalars.py +++ b/graphene/types/scalars.py @@ -1,4 +1,5 @@ import six +import types from graphql.language.ast import (BooleanValue, FloatValue, IntValue, StringValue) @@ -37,7 +38,7 @@ class Scalar(six.with_metaclass(ScalarTypeMeta, UnmountedType)): used to parse input from ast or variables and to ensure validity. ''' - def __init__(self): + def __init__(self): def get_type(self): return self self.get_type = types.MethodType(get_type, self) From 733e1f70e085240fa9a3098ded5aac2794bb3c4d Mon Sep 17 00:00:00 2001 From: Markus Padourek Date: Fri, 21 Oct 2016 10:29:49 +0100 Subject: [PATCH 4/5] Call super with args and kwargs --- graphene/types/scalars.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/graphene/types/scalars.py b/graphene/types/scalars.py index c917949e..d2263c04 100644 --- a/graphene/types/scalars.py +++ b/graphene/types/scalars.py @@ -38,7 +38,9 @@ class Scalar(six.with_metaclass(ScalarTypeMeta, UnmountedType)): used to parse input from ast or variables and to ensure validity. ''' - def __init__(self): + def __init__(self, *args, **kwargs): + super(Scalar, self).__init__(*args, **kwargs) + def get_type(self): return self self.get_type = types.MethodType(get_type, self) From e11d595f5111e5763df225f3b3934a6e9b063b74 Mon Sep 17 00:00:00 2001 From: Markus Padourek Date: Fri, 21 Oct 2016 11:22:52 +0100 Subject: [PATCH 5/5] Fixed get type instance method. --- graphene/relay/tests/test_connection.py | 4 ++-- graphene/relay/tests/test_mutation.py | 12 ++++++------ graphene/types/scalars.py | 4 ++-- graphene/types/tests/test_definition.py | 2 +- graphene/types/typemap.py | 4 +++- graphene/types/unmountedtype.py | 3 ++- 6 files changed, 16 insertions(+), 13 deletions(-) diff --git a/graphene/relay/tests/test_connection.py b/graphene/relay/tests/test_connection.py index 18d890c1..60755559 100644 --- a/graphene/relay/tests/test_connection.py +++ b/graphene/relay/tests/test_connection.py @@ -68,7 +68,7 @@ def test_edge(): assert edge_fields['node'].type == MyObject assert isinstance(edge_fields['other'], Field) - assert edge_fields['other'].type == String + assert edge_fields['other'].type.__class__ == String def test_edge_with_bases(): @@ -92,7 +92,7 @@ def test_edge_with_bases(): assert edge_fields['node'].type == MyObject assert isinstance(edge_fields['other'], Field) - assert edge_fields['other'].type == String + assert edge_fields['other'].type.__class__ == String def test_edge_on_node(): diff --git a/graphene/relay/tests/test_mutation.py b/graphene/relay/tests/test_mutation.py index 34fbb936..18d26a0b 100644 --- a/graphene/relay/tests/test_mutation.py +++ b/graphene/relay/tests/test_mutation.py @@ -81,7 +81,7 @@ def test_mutation(): assert field.args['input'].type.of_type == SaySomething.Input assert isinstance(fields['client_mutation_id'], Field) assert fields['client_mutation_id'].name == 'clientMutationId' - assert fields['client_mutation_id'].type == String + assert fields['client_mutation_id'].type.__class__ == String def test_mutation_input(): @@ -90,9 +90,9 @@ def test_mutation_input(): fields = Input._meta.fields assert list(fields.keys()) == ['what', 'client_mutation_id'] assert isinstance(fields['what'], InputField) - assert fields['what'].type == String + assert fields['what'].type.__class__ == String assert isinstance(fields['client_mutation_id'], InputField) - assert fields['client_mutation_id'].type == String + assert fields['client_mutation_id'].type.__class__ == String def test_subclassed_mutation(): @@ -113,11 +113,11 @@ def test_subclassed_mutation_input(): fields = Input._meta.fields assert list(fields.keys()) == ['shared', 'additional_field', 'client_mutation_id'] assert isinstance(fields['shared'], InputField) - assert fields['shared'].type == String + assert fields['shared'].type.__class__ == String assert isinstance(fields['additional_field'], InputField) - assert fields['additional_field'].type == String + assert fields['additional_field'].type.__class__ == String assert isinstance(fields['client_mutation_id'], InputField) - assert fields['client_mutation_id'].type == String + assert fields['client_mutation_id'].type.__class__ == String # def test_node_query(): diff --git a/graphene/types/scalars.py b/graphene/types/scalars.py index d2263c04..6b7fdb44 100644 --- a/graphene/types/scalars.py +++ b/graphene/types/scalars.py @@ -50,8 +50,8 @@ class Scalar(six.with_metaclass(ScalarTypeMeta, UnmountedType)): parse_literal = None @classmethod - def get_type(self): - return self + def get_type(cls): + return cls # As per the GraphQL Spec, Integers are only treated as valid when a valid # 32-bit signed integer, providing the broadest support across platforms. diff --git a/graphene/types/tests/test_definition.py b/graphene/types/tests/test_definition.py index b040c42d..4446b726 100644 --- a/graphene/types/tests/test_definition.py +++ b/graphene/types/tests/test_definition.py @@ -83,7 +83,7 @@ def test_defines_a_query_only_schema(): assert issubclass(article_field_type, ObjectType) title_field = article_field_type._meta.fields['title'] - assert title_field.type == String + assert title_field.type.__class__ == String author_field = article_field_type._meta.fields['author'] author_field_type = author_field.type diff --git a/graphene/types/typemap.py b/graphene/types/typemap.py index d7a7f23e..dec63ad1 100644 --- a/graphene/types/typemap.py +++ b/graphene/types/typemap.py @@ -24,7 +24,7 @@ from .utils import get_field_as def is_graphene_type(_type): - if isinstance(_type, (List, NonNull)): + if isinstance(_type, (List, NonNull, Scalar)): return True if inspect.isclass(_type) and issubclass(_type, (ObjectType, InputObjectType, Scalar, Interface, Union, Enum)): return True @@ -68,6 +68,8 @@ class TypeMap(GraphQLTypeMap): if is_graphene_type(_type): assert _type.graphene_type == type return map + if isinstance(type, Scalar): + return self.construct_scalar(map, type.__class__) if issubclass(type, ObjectType): return self.construct_objecttype(map, type) if issubclass(type, InputObjectType): diff --git a/graphene/types/unmountedtype.py b/graphene/types/unmountedtype.py index c9b36631..a08052c6 100644 --- a/graphene/types/unmountedtype.py +++ b/graphene/types/unmountedtype.py @@ -63,7 +63,8 @@ class UnmountedType(OrderedType): return ( self is other or ( isinstance(other, UnmountedType) and - self.get_type() == other.get_type() and + self.get_type()._meta == other.get_type()._meta and + # self.get_type()._meta.name == other.get_type()._meta.name and self.args == other.args and self.kwargs == other.kwargs )