WIP: Also inherit interfaces from abstract type.

This commit is contained in:
Markus Padourek 2016-08-16 19:10:46 +01:00
parent 018811036b
commit 5f573c87e4
4 changed files with 91 additions and 7 deletions

View File

@ -1,3 +1,4 @@
from collections import OrderedDict
import six
from ..utils.is_base_type import is_base_type
@ -9,26 +10,59 @@ from .utils import (get_fields_in_type, get_base_fields,
class AbstractTypeMeta(type):
def __new__(cls, name, bases, attrs):
from .interface import Interface
# Also ensure initialization is only performed for subclasses of
# AbstractType
if not is_base_type(bases, AbstractTypeMeta):
return type.__new__(cls, name, bases, attrs)
print('-----> in AbstractTypeMeta')
print(attrs.get('_meta'))
print(attrs.get('Meta'))
print(dir(attrs.get('Meta')))
for base in bases:
if not issubclass(base, AbstractType) and issubclass(type(base), AbstractTypeMeta):
# raise Exception('You can only extend AbstractTypes after the base definition.')
return type.__new__(cls, name, bases, attrs)
base_fields = get_base_fields(AbstractType, bases)
fields = get_fields_in_type(AbstractType, attrs)
yank_fields_from_attrs(attrs, fields)
options = Options(
fields=merge(base_fields, fields)
_meta = attrs.pop('_meta', None)
options = _meta or Options(
attrs.pop('Meta', None),
interfaces=(),
fields=()
)
print('options:')
print(options)
options.base_fields = get_base_fields(AbstractType, bases)
options.local_fields = get_fields_in_type(AbstractType, attrs)
yank_fields_from_attrs(attrs, options.local_fields)
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
)
# options = Options(
# fields=merge(base_fields, fields),
# interfaces=(),
# )
cls = type.__new__(cls, name, bases, dict(attrs, _meta=options))
for interface in options.interfaces:
interface.implements(cls)
return cls

View File

@ -19,6 +19,10 @@ class ObjectTypeMeta(AbstractTypeMeta):
return type.__new__(cls, name, bases, attrs)
_meta = attrs.pop('_meta', None)
base_interfaces = ()
for base in bases:
if hasattr(base, '_meta') and hasattr(base._meta, 'interfaces'):
base_interfaces = base_interfaces + base._meta.interfaces
options = _meta or Options(
attrs.pop('Meta', None),
name=name,
@ -26,13 +30,27 @@ class ObjectTypeMeta(AbstractTypeMeta):
interfaces=(),
local_fields=OrderedDict(),
)
options.interfaces = options.interfaces + base_interfaces
print('OPTIONS', options)
options.base_fields = get_base_fields(ObjectType, bases)
print('-----> base fields: ', options.base_fields)
# from ..types import AbstractType
# inherited_bases = (AbstractType, Interface)
# for base in bases:
# if base in inherited_bases or not issubclass(base, inherited_bases):
# continue
# print(base)
# print(base())
# print(dir(base()))
# print(dir(base()._meta))
if not options.local_fields:
options.local_fields = get_fields_in_type(ObjectType, attrs)
yank_fields_from_attrs(attrs, options.local_fields)
options.interface_fields = OrderedDict()
print('interfaces')
print(options.interfaces)
for interface in options.interfaces:
assert issubclass(interface, Interface), (
'All interfaces of {} must be a subclass of Interface. Received "{}".'

View File

@ -2,6 +2,7 @@ import pytest
from ..abstracttype import AbstractType
from ..field import Field
from ..scalars import String
from ..interface import Interface
from ..objecttype import ObjectType
from ..unmountedtype import UnmountedType
@ -57,6 +58,19 @@ def test_generate_objecttype_with_meta():
assert MyObjectType._meta.interfaces == (MyType, )
def test_generate_objecttype_with_interface():
class MyObjectType(ObjectType):
class Meta:
interfaces = (MyInterface, )
great_field = String()
assert MyObjectType._meta.interfaces == (MyInterface, )
assert list(MyObjectType._meta.fields.keys()) == ['ifield', 'great_field']
assert list(map(type, MyObjectType._meta.fields.values())) == [Field, Field]
def test_generate_objecttype_with_fields():
class MyObjectType(ObjectType):
field = Field(MyType)
@ -96,6 +110,20 @@ def test_generate_objecttype_inherit_abstracttype_reversed():
assert list(map(type, MyObjectType._meta.fields.values())) == [Field, Field]
def test_generate_objecttype_inherit_abstracttype_with_interface():
class MyAbstractType(AbstractType):
class Meta:
interfaces = (MyInterface, )
field1 = MyScalar()
class MyObjectType(ObjectType, MyAbstractType):
field2 = MyScalar()
assert MyObjectType._meta.interfaces == (MyInterface, )
assert list(MyObjectType._meta.fields.keys()) == ['ifield', 'field1', 'field2']
assert list(map(type, MyObjectType._meta.fields.values())) == [Field, Field, Field]
def test_generate_objecttype_unmountedtype():
class MyObjectType(ObjectType):
field = MyScalar()

View File

@ -12,6 +12,10 @@ def merge_fields_in_attrs(bases, attrs):
for base in bases:
if base in inherited_bases or not issubclass(base, inherited_bases):
continue
print('!!!!!!!!!!!')
print(base._meta)
print(dir(base._meta))
print(base._meta.fields.items())
for name, field in base._meta.fields.items():
if name in attrs:
continue