mirror of
https://github.com/graphql-python/graphene.git
synced 2025-07-25 23:39:49 +03:00
WIP: Also inherit interfaces from abstract type.
This commit is contained in:
parent
018811036b
commit
5f573c87e4
|
@ -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
|
||||
|
||||
|
||||
|
|
|
@ -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 "{}".'
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue
Block a user