mirror of
https://github.com/graphql-python/graphene.git
synced 2025-02-02 12:44:15 +03:00
Improved fields inheritance in ObjectTypes
This commit is contained in:
parent
2410841753
commit
32e4a21403
|
@ -17,6 +17,10 @@ from graphene.core.types import BaseObjectType
|
|||
from graphene.core.scalars import GraphQLSkipField
|
||||
|
||||
|
||||
class Empty(object):
|
||||
pass
|
||||
|
||||
|
||||
@total_ordering
|
||||
class Field(object):
|
||||
SKIP = GraphQLSkipField
|
||||
|
@ -142,6 +146,14 @@ class Field(object):
|
|||
def __hash__(self):
|
||||
return hash(self.creation_counter)
|
||||
|
||||
def __copy__(self):
|
||||
# We need to avoid hitting __reduce__, so define this
|
||||
# slightly weird copy construct.
|
||||
obj = Empty()
|
||||
obj.__class__ = self.__class__
|
||||
obj.__dict__ = self.__dict__.copy()
|
||||
return obj
|
||||
|
||||
|
||||
class NativeField(Field):
|
||||
|
||||
|
|
|
@ -64,10 +64,7 @@ class Options(object):
|
|||
|
||||
@cached_property
|
||||
def fields(self):
|
||||
fields = []
|
||||
for parent in self.parents:
|
||||
fields.extend(parent._meta.fields)
|
||||
return sorted(self.local_fields + fields)
|
||||
return sorted(self.local_fields)
|
||||
|
||||
@cached_property
|
||||
def fields_map(self):
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import inspect
|
||||
import six
|
||||
import copy
|
||||
from collections import OrderedDict
|
||||
|
||||
from graphql.core.type import (
|
||||
|
@ -72,13 +73,20 @@ class ObjectTypeMeta(type):
|
|||
# on the base classes (we cannot handle shadowed fields at the
|
||||
# moment).
|
||||
for field in parent_fields:
|
||||
if field.name in field_names and field.__class__ != field_names[field].__class__:
|
||||
if field.name in field_names and field.__class__ != field_names[field.name].__class__:
|
||||
raise Exception(
|
||||
'Local field %r in class %r clashes '
|
||||
'with field of similar name from '
|
||||
'base class %r' % (
|
||||
field.name, name, base.__name__)
|
||||
'with field with similar name from '
|
||||
'Interface %s (%r != %r)' % (
|
||||
field.name,
|
||||
new_class.__name__,
|
||||
base.__name__,
|
||||
field.__class__,
|
||||
field_names[field.name].__class__)
|
||||
)
|
||||
new_field = copy.copy(field)
|
||||
new_class.add_to_class(field.field_name, new_field)
|
||||
|
||||
new_class._meta.parents.append(base)
|
||||
if base._meta.interface:
|
||||
new_class._meta.interfaces.append(base)
|
||||
|
|
|
@ -3,6 +3,7 @@ from collections import namedtuple
|
|||
from pytest import raises
|
||||
from graphene.core.fields import (
|
||||
Field,
|
||||
IntField,
|
||||
StringField,
|
||||
)
|
||||
from graphql.core.type import (
|
||||
|
@ -60,3 +61,10 @@ def test_object_type():
|
|||
assert object_type.get_fields() == {'name': Character._meta.fields_map['name'].internal_field(
|
||||
schema), 'friends': Human._meta.fields_map['friends'].internal_field(schema)}
|
||||
assert object_type.get_interfaces() == [Character.internal_type(schema)]
|
||||
|
||||
|
||||
def test_field_clashes():
|
||||
with raises(Exception) as excinfo:
|
||||
class Droid(Character):
|
||||
name = IntField()
|
||||
assert 'clashes' in str(excinfo.value)
|
||||
|
|
Loading…
Reference in New Issue
Block a user