Simplified ObjectType logic

This commit is contained in:
Syrus Akbary 2017-07-11 20:53:49 -07:00
parent c98d91ba1c
commit e487206818
2 changed files with 42 additions and 69 deletions

View File

@ -3,13 +3,13 @@ from ..utils.trim_docstring import trim_docstring
class BaseOptions(object): class BaseOptions(object):
name = None name = None # type: str
description = None description = None # type: str
_frozen = False _frozen = False # type: bool
def __init__(self, class_type): def __init__(self, class_type):
self.class_type = class_type self.class_type = class_type # type: Type
def freeze(self): def freeze(self):
self._frozen = True self._frozen = True

View File

@ -1,82 +1,55 @@
from collections import OrderedDict from collections import OrderedDict
import six
from ..utils.is_base_type import is_base_type
from ..utils.trim_docstring import trim_docstring
from .abstracttype import AbstractTypeMeta
from .field import Field from .field import Field
from .interface import Interface from .interface import Interface
from .options import Options from .utils import yank_fields_from_attrs
from .utils import get_base_fields, merge, yank_fields_from_attrs
from .base import BaseOptions, BaseType
class ObjectTypeMeta(AbstractTypeMeta): class ObjectTypeOptions(BaseOptions):
fields = None # type: Dict[str, Field]
def __new__(cls, name, bases, attrs): interfaces = () # type: List[Type[Interface]]
# Also ensure initialization is only performed for subclasses of
# ObjectType
if not is_base_type(bases, ObjectTypeMeta):
return type.__new__(cls, name, bases, attrs)
_meta = attrs.pop('_meta', None)
defaults = dict(
name=name,
description=trim_docstring(attrs.get('__doc__')),
interfaces=(),
possible_types=(),
default_resolver=None,
local_fields=OrderedDict(),
)
if not _meta:
options = Options(
attrs.pop('Meta', None),
**defaults
)
else:
options = _meta.extend_with_defaults(defaults)
options.base_fields = get_base_fields(bases, _as=Field)
if not options.local_fields:
options.local_fields = yank_fields_from_attrs(attrs=attrs, _as=Field)
options.interface_fields = OrderedDict()
for interface in options.interfaces:
assert issubclass(interface, Interface), (
'All interfaces of {} must be a subclass of Interface. Received "{}".'
).format(name, interface)
options.interface_fields.update(interface._meta.fields)
options.fields = merge(
options.interface_fields,
options.base_fields,
options.local_fields
)
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)
return cls
def __str__(cls): # noqa: N802
return cls._meta.name
class ObjectType(six.with_metaclass(ObjectTypeMeta)): class ObjectTypeMeta(type):
pass
class ObjectType(BaseType):
''' '''
Object Type Definition Object Type Definition
Almost all of the GraphQL types you define will be object types. Object types Almost all of the GraphQL types you define will be object types. Object types
have a name, but most importantly describe their fields. have a name, but most importantly describe their fields.
''' '''
@classmethod
def __init_subclass_with_meta__(cls, interfaces=(), possible_types=(), default_resolver=None, **options):
_meta = ObjectTypeOptions(cls)
fields = OrderedDict()
for interface in interfaces:
assert issubclass(interface, Interface), (
'All interfaces of {} must be a subclass of Interface. Received "{}".'
).format(name, interface)
fields.update(interface._meta.fields)
for base in reversed(cls.__mro__):
fields.update(
yank_fields_from_attrs(base.__dict__, _as=Field)
)
assert not (possible_types and cls.is_type_of), (
'{name}.Meta.possible_types will cause type collision with {name}.is_type_of. '
'Please use one or other.'
).format(name=cls.__name__)
_meta.fields = fields
_meta.interfaces = interfaces
_meta.possible_types = possible_types
_meta.default_resolver = default_resolver
super(ObjectType, cls).__init_subclass_with_meta__(_meta=_meta, **options)
is_type_of = None is_type_of = None