Skip to content

ObjectType.resolve_type classmethod makes it impossible to have a field named 'type' #50

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
inklesspen opened this issue Nov 25, 2015 · 6 comments

Comments

@inklesspen
Copy link
Contributor

The resolve_type method on ObjectType conflicts with actually resolving a field called type. Given the importance of resolve method names, I think great care should be taken to make sure graphene's codebase does not use these method names unless necessary.

The below test fails with GraphQLError("'Location' object has no attribute 'T'",); renaming the resolve_type method to _resolve_type solves the problem.

import graphene
from graphql.core.type import GraphQLEnumValue


LOCATION_TYPES = {
    'HQ': "Headquarters",
    'BRANCH': "Branch Location",
}


LOCATIONS = {
    '1': {
        'type': 'HQ',
        'address': '123 Main St',
        'city': 'Metropolis',
    },
    '2': {
        'type': 'BRANCH',
        'address': '55 Side St',
        'city': 'Smallville',
    },
}


LocationType = graphene.Enum(
    'LocationType',
    {k: GraphQLEnumValue(value=k, description=v) for k, v in LOCATION_TYPES.items()}
)


class Location(graphene.ObjectType):
    type = graphene.NonNull(LocationType)
    address = graphene.NonNull(graphene.String())
    city = graphene.NonNull(graphene.String())


class Query(graphene.ObjectType):
    location = graphene.Field(Location, id=graphene.ID(description='location id'))

    def resolve_location(self, args, info):
        loc_id = args.get('id')
        # error checking ommitted for brevity
        return Location(**LOCATIONS[loc_id])


schema = graphene.Schema(name="Sample", query=Query)

EXPECTED_SCHEMA = """
type Location {
  type: LocationType!
  address: String!
  city: String!
}

enum LocationType {
  BRANCH
  HQ
}

type Query {
  location(id: ID): Location
}
""".lstrip()

QUERY = """
fragment locFields on Location {
  type
  address
  city
}

query SomeQuery {
  hq: location(id: 1) {
    ...locFields
  }
  branch: location(id: 2) {
    ...locFields
  }

}
""".lstrip()

EXPECTED_RESPONSE = {
    'hq': {
        'type': 'HQ',
        'address': '123 Main St',
        'city': 'Metropolis'
    },
    'branch': {
        'type': 'BRANCH',
        'address': '55 Side St',
        'city': 'Smallville'
    },
}


def test_type():
    assert str(schema) == EXPECTED_SCHEMA
    result = schema.execute(QUERY)
    assert not result.errors
    assert result.data == EXPECTED_RESPONSE
@syrusakbary
Copy link
Member

Thanks for such a detailed example @inklesspen.
Will fix this in the next commit.

p0123n pushed a commit to p0123n/graphene that referenced this issue Aug 26, 2017
Added sqlalchemy utils type TSVectory
@svilendobrev
Copy link

this is still a problem on graphene.Interface - resolve_type is a classmethod there..

@jkimbo
Copy link
Member

jkimbo commented Jun 21, 2018

Ha, that is a good point @svilendobrev !

@syrusakbary should probably rename the function to _resolve_type and do it soon since it's now documented. I guess it's technically a breaking change but I don't think it's extensively used so we can probably get away with releasing it in 2.2 version

@cherls
Copy link
Contributor

cherls commented Nov 22, 2018

Using type as a variable is an anti-pattern in Python as it overwrites a built-in function, not to mention the use of type in GraphQL Schemas. The better alternative, in my opinion, would be to rename the field as location_type or type_.

@inklesspen
Copy link
Contributor Author

Using type as a variable in Python code and using type as a field in a schema to send data between several systems, many of which may not be written in Python, are two different scenarios.

@stale
Copy link

stale bot commented Jul 29, 2019

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@stale stale bot added the wontfix label Jul 29, 2019
@stale stale bot closed this as completed Aug 5, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants