Skip to content

Interface.resolve_type classmethod makes it impossible to have a field named 'type' #899

@lexdene

Description

@lexdene

The resolve_type method on Interface conflicts with actually resolving a field called type.

The below test fails with GraphQLError('Expected a value of type "Color" but received: RedItem',).

from graphene import (
    Schema,
    ObjectType, Interface, Field,
    List, Enum, Int, String,
)


class ItemData(object):
    def __init__(self, data):
        self.data = data

    def __getattr__(self, key):
        return self.data[key]


class Color(Enum):
    red = 1
    green = 2
    blue = 3


class Item(Interface):
    id = Int()
    type = Field(Color)

    @classmethod
    def resolve_type(cls, instance, info):
        if instance.type == Color.red.value:
            return RedItem
        elif instance.type == Color.green.value:
            return GreenItem
        elif instance.type == Color.blue.value:
            return BlueItem


class RedItem(ObjectType):
    foo = String()

    class Meta:
        interfaces = Item,


class GreenItem(ObjectType):
    bar = String()

    class Meta:
        interfaces = Item,


class BlueItem(ObjectType):
    baz = String()

    class Meta:
        interfaces = Item,


class Query(ObjectType):
    get_items = List(Item)

    def resolve_get_items(self, info):
        items = [
            {
                "id": 4921312,
                "type": 1,
                "foo": "blahblah"
            },
            {
                "id": 3137806,
                "type": 2,
                "bar": "clahclah",
            },
            {
                "id": 9781512,
                "type": 3,
                "baz": "dlahdlah",
            },
        ]

        return [ItemData(i) for i in items]


schema = Schema(
    query=Query,
    types=[RedItem, GreenItem, BlueItem],
)

QUERY = '''
fragment itemFields on Item {
  id
  type
  ... on RedItem {
      foo
  }
  ... on GreenItem {
      bar
  }
  ... on BlueItem {
      baz
  }
}
query SomeQuery {
  getItems{
    ... itemFields
  }
}
'''

EXPECTED_RESPONSE = {
    'getItems': [
        {
            'id': 4921312,
            'type': 'red',
            'foo': 'blahblah',
        },
        {
            'id': 3137806,
            'type': 'green',
            'bar': 'clahclah',
        },
        {
            'id': 9781512,
            'type': 'blue',
            'baz': 'dlahdlah',
        },
    ]
}


def main():
    result = schema.execute(QUERY)
    assert not result.errors
    assert result.data == EXPECTED_RESPONSE

Metadata

Metadata

Assignees

No one assigned

    Labels

    3.0Fix/Release version 3.0wontfix

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions