mirror of
https://github.com/graphql-python/graphene.git
synced 2024-11-11 04:07:16 +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
|
from graphene.core.scalars import GraphQLSkipField
|
||||||
|
|
||||||
|
|
||||||
|
class Empty(object):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
@total_ordering
|
@total_ordering
|
||||||
class Field(object):
|
class Field(object):
|
||||||
SKIP = GraphQLSkipField
|
SKIP = GraphQLSkipField
|
||||||
|
@ -142,6 +146,14 @@ class Field(object):
|
||||||
def __hash__(self):
|
def __hash__(self):
|
||||||
return hash(self.creation_counter)
|
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):
|
class NativeField(Field):
|
||||||
|
|
||||||
|
|
|
@ -64,10 +64,7 @@ class Options(object):
|
||||||
|
|
||||||
@cached_property
|
@cached_property
|
||||||
def fields(self):
|
def fields(self):
|
||||||
fields = []
|
return sorted(self.local_fields)
|
||||||
for parent in self.parents:
|
|
||||||
fields.extend(parent._meta.fields)
|
|
||||||
return sorted(self.local_fields + fields)
|
|
||||||
|
|
||||||
@cached_property
|
@cached_property
|
||||||
def fields_map(self):
|
def fields_map(self):
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import inspect
|
import inspect
|
||||||
import six
|
import six
|
||||||
|
import copy
|
||||||
from collections import OrderedDict
|
from collections import OrderedDict
|
||||||
|
|
||||||
from graphql.core.type import (
|
from graphql.core.type import (
|
||||||
|
@ -72,13 +73,20 @@ class ObjectTypeMeta(type):
|
||||||
# on the base classes (we cannot handle shadowed fields at the
|
# on the base classes (we cannot handle shadowed fields at the
|
||||||
# moment).
|
# moment).
|
||||||
for field in parent_fields:
|
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(
|
raise Exception(
|
||||||
'Local field %r in class %r clashes '
|
'Local field %r in class %r clashes '
|
||||||
'with field of similar name from '
|
'with field with similar name from '
|
||||||
'base class %r' % (
|
'Interface %s (%r != %r)' % (
|
||||||
field.name, name, base.__name__)
|
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)
|
new_class._meta.parents.append(base)
|
||||||
if base._meta.interface:
|
if base._meta.interface:
|
||||||
new_class._meta.interfaces.append(base)
|
new_class._meta.interfaces.append(base)
|
||||||
|
|
|
@ -3,6 +3,7 @@ from collections import namedtuple
|
||||||
from pytest import raises
|
from pytest import raises
|
||||||
from graphene.core.fields import (
|
from graphene.core.fields import (
|
||||||
Field,
|
Field,
|
||||||
|
IntField,
|
||||||
StringField,
|
StringField,
|
||||||
)
|
)
|
||||||
from graphql.core.type import (
|
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(
|
assert object_type.get_fields() == {'name': Character._meta.fields_map['name'].internal_field(
|
||||||
schema), 'friends': Human._meta.fields_map['friends'].internal_field(schema)}
|
schema), 'friends': Human._meta.fields_map['friends'].internal_field(schema)}
|
||||||
assert object_type.get_interfaces() == [Character.internal_type(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