Skip to content

Commit ad251e9

Browse files
committed
Fix ObjectType special types. Fix #425
1 parent 98825fa commit ad251e9

File tree

3 files changed

+62
-1
lines changed

3 files changed

+62
-1
lines changed

graphene/tests/issues/test_425.py

+53
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
# https://github.com/graphql-python/graphene/issues/425
2+
import six
3+
4+
from graphene.utils.is_base_type import is_base_type
5+
6+
from graphene.types.objecttype import ObjectTypeMeta, ObjectType
7+
from graphene.types.options import Options
8+
9+
class SpecialObjectTypeMeta(ObjectTypeMeta):
10+
11+
@staticmethod
12+
def __new__(cls, name, bases, attrs):
13+
# Also ensure initialization is only performed for subclasses of
14+
# DjangoObjectType
15+
if not is_base_type(bases, SpecialObjectTypeMeta):
16+
return type.__new__(cls, name, bases, attrs)
17+
18+
options = Options(
19+
attrs.pop('Meta', None),
20+
other_attr='default',
21+
)
22+
23+
return ObjectTypeMeta.__new__(cls, name, bases, dict(attrs, _meta=options))
24+
25+
return cls
26+
27+
28+
class SpecialObjectType(six.with_metaclass(SpecialObjectTypeMeta, ObjectType)):
29+
pass
30+
31+
32+
def test_special_objecttype_could_be_subclassed():
33+
class MyType(SpecialObjectType):
34+
class Meta:
35+
other_attr = 'yeah!'
36+
37+
assert MyType._meta.other_attr == 'yeah!'
38+
39+
40+
def test_special_objecttype_could_be_subclassed_default():
41+
class MyType(SpecialObjectType):
42+
pass
43+
44+
assert MyType._meta.other_attr == 'default'
45+
46+
47+
def test_special_objecttype_inherit_meta_options():
48+
class MyType(SpecialObjectType):
49+
pass
50+
51+
assert MyType._meta.name == 'MyType'
52+
assert MyType._meta.default_resolver == None
53+
assert MyType._meta.interfaces == ()

graphene/types/objecttype.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ def __new__(cls, name, bases, attrs):
1919
if not is_base_type(bases, ObjectTypeMeta):
2020
return type.__new__(cls, name, bases, attrs)
2121

22-
attrs.pop('_meta', None)
22+
_meta = attrs.pop('_meta', None)
2323
options = Options(
2424
attrs.pop('Meta', None),
2525
name=name,
@@ -28,6 +28,7 @@ def __new__(cls, name, bases, attrs):
2828
default_resolver=None,
2929
local_fields=OrderedDict(),
3030
)
31+
options.extend_with_meta(_meta)
3132
options.base_fields = get_base_fields(bases, _as=Field)
3233

3334
if not options.local_fields:

graphene/types/options.py

+7
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,13 @@ def __init__(self, meta=None, **defaults):
3030
)
3131
)
3232

33+
def extend_with_meta(self, meta):
34+
if not meta:
35+
return
36+
meta_attrs = props(meta)
37+
for attr_name, value in meta_attrs.items():
38+
setattr(self, attr_name, value)
39+
3340
def __repr__(self):
3441
options_props = props(self)
3542
props_as_attrs = ' '.join(['{}={}'.format(key, value) for key, value in options_props.items()])

0 commit comments

Comments
 (0)