Added possible_types option to ObjectType.Meta

This commit is contained in:
Syrus Akbary 2017-04-14 22:32:12 -07:00
parent e3663d41ce
commit a7511d3a2c
4 changed files with 55 additions and 1 deletions

View File

@ -24,6 +24,7 @@ class ObjectTypeMeta(AbstractTypeMeta):
name=name,
description=trim_docstring(attrs.get('__doc__')),
interfaces=(),
possible_types=(),
default_resolver=None,
local_fields=OrderedDict(),
)
@ -55,6 +56,11 @@ class ObjectTypeMeta(AbstractTypeMeta):
cls = type.__new__(cls, name, bases, dict(attrs, _meta=options))
assert not (options.possible_types and cls.is_type_of), (
'{}.Meta.possible_types will cause type collision with {}.is_type_of. '
'Please use one or other.'
).format(name, name)
for interface in options.interfaces:
interface.implements(cls)

View File

@ -184,3 +184,27 @@ def test_generate_objecttype_description():
'''
assert MyObjectType._meta.description == "Documentation\n\nDocumentation line 2"
def test_objecttype_with_possible_types():
class MyObjectType(ObjectType):
class Meta:
possible_types = (dict, )
assert MyObjectType._meta.possible_types == (dict, )
def test_objecttype_with_possible_types_and_is_type_of_should_raise():
with pytest.raises(AssertionError) as excinfo:
class MyObjectType(ObjectType):
class Meta:
possible_types = (dict, )
@classmethod
def is_type_of(cls, root, context, info):
return False
assert str(excinfo.value) == (
'MyObjectType.Meta.possible_types will cause type collision with '
'MyObjectType.is_type_of. Please use one or other.'
)

View File

@ -183,3 +183,18 @@ def test_objecttype_camelcase_disabled():
assert foo_field.args == {
'bar_foo': GraphQLArgument(GraphQLString, out_name='bar_foo')
}
def test_objecttype_with_possible_types():
class MyObjectType(ObjectType):
'''Description'''
class Meta:
possible_types = (dict, )
foo_bar = String()
typemap = TypeMap([MyObjectType])
graphql_type = typemap['MyObjectType']
assert graphql_type.is_type_of
assert graphql_type.is_type_of({}, None, None) is True
assert graphql_type.is_type_of(MyObjectType(), None, None) is False

View File

@ -52,6 +52,10 @@ def resolve_type(resolve_type_func, map, type_name, root, context, info):
return _type
def is_type_of_from_possible_types(possible_types, root, context, info):
return isinstance(root, possible_types)
class TypeMap(GraphQLTypeMap):
def __init__(self, types, auto_camelcase=True, schema=None):
@ -153,12 +157,17 @@ class TypeMap(GraphQLTypeMap):
interfaces.append(internal_type)
return interfaces
if type._meta.possible_types:
is_type_of = partial(is_type_of_from_possible_types, type._meta.possible_types)
else:
is_type_of = type.is_type_of
return GrapheneObjectType(
graphene_type=type,
name=type._meta.name,
description=type._meta.description,
fields=partial(self.construct_fields_for_type, map, type),
is_type_of=type.is_type_of,
is_type_of=is_type_of,
interfaces=interfaces
)