diff --git a/graphene/types/scalars.py b/graphene/types/scalars.py index cf4a115e..bf01420c 100644 --- a/graphene/types/scalars.py +++ b/graphene/types/scalars.py @@ -1,29 +1,37 @@ import six from graphql import GraphQLScalarType, GraphQLString, GraphQLInt, GraphQLFloat, GraphQLBoolean, GraphQLID -from .definitions import ClassTypeMeta, GrapheneGraphQLType +from .definitions import GrapheneGraphQLType from .unmountedtype import UnmountedType +from .options import Options +from ..utils.is_base_type import is_base_type class GrapheneScalarType(GrapheneGraphQLType, GraphQLScalarType): pass -class ScalarTypeMeta(ClassTypeMeta): +class ScalarTypeMeta(type): - def get_options(cls, meta): - return cls.options_class( - meta, + def __new__(cls, name, bases, attrs): + super_new = super(ScalarTypeMeta, cls).__new__ + + # Also ensure initialization is only performed for subclasses of Model + # (excluding Model class itself). + if not is_base_type(bases, ScalarTypeMeta): + return super_new(cls, name, bases, attrs) + + options = Options( + attrs.pop('Meta', None), name=None, description=None, - graphql_type=None, - abstract=False + graphql_type=None ) - def construct(cls, *args, **kwargs): - constructed = super(ScalarTypeMeta, cls).construct(*args, **kwargs) - if not cls._meta.graphql_type and not cls._meta.abstract: - cls._meta.graphql_type = GrapheneScalarType( + cls = super_new(cls, name, bases, dict(attrs, _meta=options)) + + if not options.graphql_type: + options.graphql_type = GrapheneScalarType( graphene_type=cls, name=cls._meta.name or cls.__name__, description=cls._meta.description or cls.__doc__, @@ -33,12 +41,11 @@ class ScalarTypeMeta(ClassTypeMeta): parse_literal=getattr(cls, 'parse_literal', None), ) - return constructed + return cls class Scalar(six.with_metaclass(ScalarTypeMeta, UnmountedType)): - class Meta: - abstract = True + pass def construct_scalar_class(graphql_type): diff --git a/graphene/utils/get_graphql_type.py b/graphene/utils/get_graphql_type.py index fe182c4c..74d6ea5a 100644 --- a/graphene/utils/get_graphql_type.py +++ b/graphene/utils/get_graphql_type.py @@ -7,8 +7,6 @@ def get_graphql_type(_type): if is_type(_type): return _type elif is_graphene_type(_type): - if _type._meta.abstract: - raise Exception("{} has no type. Only non abstract types have GraphQL type.".format(_type.__name__)) return _type._meta.graphql_type raise Exception("Cannot get GraphQL type of {}.".format(_type)) diff --git a/graphene/utils/tests/test_get_graphql_type.py b/graphene/utils/tests/test_get_graphql_type.py index ba936151..75b1232f 100644 --- a/graphene/utils/tests/test_get_graphql_type.py +++ b/graphene/utils/tests/test_get_graphql_type.py @@ -19,17 +19,6 @@ def test_get_graphql_type_graphene(): assert is_type(get_graphql_type(MyGrapheneType)) -def test_get_graphql_type_graphene_abstract(): - class MyGrapheneType(ObjectType): - class Meta: - abstract = True - - with pytest.raises(Exception) as excinfo: - get_graphql_type(MyGrapheneType) - - assert "MyGrapheneType has no type. Only non abstract types have GraphQL type." == str(excinfo.value) - - def test_get_graphql_type_custom_graphene_type(): class MyGrapheneType(ObjectType): class Meta: