Fix ObjectType special types. Fix #425

This commit is contained in:
Syrus Akbary 2017-02-26 21:09:21 -08:00
parent 98825fa4bc
commit ad251e9a8d
3 changed files with 62 additions and 1 deletions

View File

@ -0,0 +1,53 @@
# https://github.com/graphql-python/graphene/issues/425
import six
from graphene.utils.is_base_type import is_base_type
from graphene.types.objecttype import ObjectTypeMeta, ObjectType
from graphene.types.options import Options
class SpecialObjectTypeMeta(ObjectTypeMeta):
@staticmethod
def __new__(cls, name, bases, attrs):
# Also ensure initialization is only performed for subclasses of
# DjangoObjectType
if not is_base_type(bases, SpecialObjectTypeMeta):
return type.__new__(cls, name, bases, attrs)
options = Options(
attrs.pop('Meta', None),
other_attr='default',
)
return ObjectTypeMeta.__new__(cls, name, bases, dict(attrs, _meta=options))
return cls
class SpecialObjectType(six.with_metaclass(SpecialObjectTypeMeta, ObjectType)):
pass
def test_special_objecttype_could_be_subclassed():
class MyType(SpecialObjectType):
class Meta:
other_attr = 'yeah!'
assert MyType._meta.other_attr == 'yeah!'
def test_special_objecttype_could_be_subclassed_default():
class MyType(SpecialObjectType):
pass
assert MyType._meta.other_attr == 'default'
def test_special_objecttype_inherit_meta_options():
class MyType(SpecialObjectType):
pass
assert MyType._meta.name == 'MyType'
assert MyType._meta.default_resolver == None
assert MyType._meta.interfaces == ()

View File

@ -19,7 +19,7 @@ class ObjectTypeMeta(AbstractTypeMeta):
if not is_base_type(bases, ObjectTypeMeta): if not is_base_type(bases, ObjectTypeMeta):
return type.__new__(cls, name, bases, attrs) return type.__new__(cls, name, bases, attrs)
attrs.pop('_meta', None) _meta = attrs.pop('_meta', None)
options = Options( options = Options(
attrs.pop('Meta', None), attrs.pop('Meta', None),
name=name, name=name,
@ -28,6 +28,7 @@ class ObjectTypeMeta(AbstractTypeMeta):
default_resolver=None, default_resolver=None,
local_fields=OrderedDict(), local_fields=OrderedDict(),
) )
options.extend_with_meta(_meta)
options.base_fields = get_base_fields(bases, _as=Field) options.base_fields = get_base_fields(bases, _as=Field)
if not options.local_fields: if not options.local_fields:

View File

@ -30,6 +30,13 @@ class Options(object):
) )
) )
def extend_with_meta(self, meta):
if not meta:
return
meta_attrs = props(meta)
for attr_name, value in meta_attrs.items():
setattr(self, attr_name, value)
def __repr__(self): def __repr__(self):
options_props = props(self) options_props = props(self)
props_as_attrs = ' '.join(['{}={}'.format(key, value) for key, value in options_props.items()]) props_as_attrs = ' '.join(['{}={}'.format(key, value) for key, value in options_props.items()])