mirror of
https://github.com/graphql-python/graphene.git
synced 2025-07-26 07:49:53 +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
|
import six
|
||||||
|
|
||||||
from ..utils.is_base_type import is_base_type
|
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):
|
class AbstractTypeMeta(type):
|
||||||
|
|
||||||
def __new__(cls, name, bases, attrs):
|
def __new__(cls, name, bases, attrs):
|
||||||
|
from .interface import Interface
|
||||||
# Also ensure initialization is only performed for subclasses of
|
# Also ensure initialization is only performed for subclasses of
|
||||||
# AbstractType
|
# AbstractType
|
||||||
if not is_base_type(bases, AbstractTypeMeta):
|
if not is_base_type(bases, AbstractTypeMeta):
|
||||||
return type.__new__(cls, name, bases, attrs)
|
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:
|
for base in bases:
|
||||||
if not issubclass(base, AbstractType) and issubclass(type(base), AbstractTypeMeta):
|
if not issubclass(base, AbstractType) and issubclass(type(base), AbstractTypeMeta):
|
||||||
# raise Exception('You can only extend AbstractTypes after the base definition.')
|
# raise Exception('You can only extend AbstractTypes after the base definition.')
|
||||||
return type.__new__(cls, name, bases, attrs)
|
return type.__new__(cls, name, bases, attrs)
|
||||||
|
|
||||||
base_fields = get_base_fields(AbstractType, bases)
|
_meta = attrs.pop('_meta', None)
|
||||||
|
options = _meta or Options(
|
||||||
fields = get_fields_in_type(AbstractType, attrs)
|
attrs.pop('Meta', None),
|
||||||
yank_fields_from_attrs(attrs, fields)
|
interfaces=(),
|
||||||
|
fields=()
|
||||||
options = Options(
|
|
||||||
fields=merge(base_fields, 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))
|
cls = type.__new__(cls, name, bases, dict(attrs, _meta=options))
|
||||||
|
|
||||||
|
for interface in options.interfaces:
|
||||||
|
interface.implements(cls)
|
||||||
|
|
||||||
return cls
|
return cls
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,10 @@ class ObjectTypeMeta(AbstractTypeMeta):
|
||||||
return type.__new__(cls, name, bases, attrs)
|
return type.__new__(cls, name, bases, attrs)
|
||||||
|
|
||||||
_meta = attrs.pop('_meta', None)
|
_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(
|
options = _meta or Options(
|
||||||
attrs.pop('Meta', None),
|
attrs.pop('Meta', None),
|
||||||
name=name,
|
name=name,
|
||||||
|
@ -26,13 +30,27 @@ class ObjectTypeMeta(AbstractTypeMeta):
|
||||||
interfaces=(),
|
interfaces=(),
|
||||||
local_fields=OrderedDict(),
|
local_fields=OrderedDict(),
|
||||||
)
|
)
|
||||||
|
options.interfaces = options.interfaces + base_interfaces
|
||||||
|
print('OPTIONS', options)
|
||||||
options.base_fields = get_base_fields(ObjectType, bases)
|
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:
|
if not options.local_fields:
|
||||||
options.local_fields = get_fields_in_type(ObjectType, attrs)
|
options.local_fields = get_fields_in_type(ObjectType, attrs)
|
||||||
yank_fields_from_attrs(attrs, options.local_fields)
|
yank_fields_from_attrs(attrs, options.local_fields)
|
||||||
|
|
||||||
options.interface_fields = OrderedDict()
|
options.interface_fields = OrderedDict()
|
||||||
|
print('interfaces')
|
||||||
|
print(options.interfaces)
|
||||||
for interface in options.interfaces:
|
for interface in options.interfaces:
|
||||||
assert issubclass(interface, Interface), (
|
assert issubclass(interface, Interface), (
|
||||||
'All interfaces of {} must be a subclass of Interface. Received "{}".'
|
'All interfaces of {} must be a subclass of Interface. Received "{}".'
|
||||||
|
|
|
@ -2,6 +2,7 @@ import pytest
|
||||||
|
|
||||||
from ..abstracttype import AbstractType
|
from ..abstracttype import AbstractType
|
||||||
from ..field import Field
|
from ..field import Field
|
||||||
|
from ..scalars import String
|
||||||
from ..interface import Interface
|
from ..interface import Interface
|
||||||
from ..objecttype import ObjectType
|
from ..objecttype import ObjectType
|
||||||
from ..unmountedtype import UnmountedType
|
from ..unmountedtype import UnmountedType
|
||||||
|
@ -57,6 +58,19 @@ def test_generate_objecttype_with_meta():
|
||||||
assert MyObjectType._meta.interfaces == (MyType, )
|
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():
|
def test_generate_objecttype_with_fields():
|
||||||
class MyObjectType(ObjectType):
|
class MyObjectType(ObjectType):
|
||||||
field = Field(MyType)
|
field = Field(MyType)
|
||||||
|
@ -96,6 +110,20 @@ def test_generate_objecttype_inherit_abstracttype_reversed():
|
||||||
assert list(map(type, MyObjectType._meta.fields.values())) == [Field, Field]
|
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():
|
def test_generate_objecttype_unmountedtype():
|
||||||
class MyObjectType(ObjectType):
|
class MyObjectType(ObjectType):
|
||||||
field = MyScalar()
|
field = MyScalar()
|
||||||
|
|
|
@ -12,6 +12,10 @@ def merge_fields_in_attrs(bases, attrs):
|
||||||
for base in bases:
|
for base in bases:
|
||||||
if base in inherited_bases or not issubclass(base, inherited_bases):
|
if base in inherited_bases or not issubclass(base, inherited_bases):
|
||||||
continue
|
continue
|
||||||
|
print('!!!!!!!!!!!')
|
||||||
|
print(base._meta)
|
||||||
|
print(dir(base._meta))
|
||||||
|
print(base._meta.fields.items())
|
||||||
for name, field in base._meta.fields.items():
|
for name, field in base._meta.fields.items():
|
||||||
if name in attrs:
|
if name in attrs:
|
||||||
continue
|
continue
|
||||||
|
|
Loading…
Reference in New Issue
Block a user