Skip to content

Argument of type SomeEnum does not map back to SomeEnum.VALUE when used as an argument #444

@dewiniaid

Description

@dewiniaid

I couldn't figure out how to succinctly word the summary.

When receiving an Enum as an argument, it's not possible to compare it against the class that defined it. That is, args['episode'] == Episode.NEWHOPE will be False on query { foo(episode:NEWHOPE) }. This seems counter-intuitive

class Episode(Enum):
    NEWHOPE = 4
    EMPIRE = 5
    JEDI = 6


class Query(ObjectType):
    foo = String(
        args={'blah': Episode(default_value=Episode.NEWHOPE)}
    )

    def resolve_foo(self, args, context, info):
        import sys

        blah = args.get('blah')
        return (
            "Value of blah is: {!r}\n"
            "(blah == NEWHOPE) is: {!r}\n"
            "Python version is: {!r}\n"
            ""
        ).format(
            blah,
            blah == Episode.NEWHOPE,
            sys.version
        )
query {
  foo(blah:NEWHOPE)
}

yields (de-JSOnified for easier reading):

Value of blah is: 4
(blah == NEWHOPE) is: False
Python version is: '3.5.2 (default, Nov 17 2016, 17:05:23) \\n[GCC 5.4.0 20160609]'

"Native" Enums don't compare to their 'actual' representation either...

>>> import enum
>>> class Episode(enum.Enum):
...     NEWHOPE = 4
...
>>> Episode.NEWHOPE == 4
False

... but they can be converted; e.g. Episode(4) == Episode.NEWHOPE, which does not work in Graphene. Additionally, Python's IntEnum class does permit straight comparisons to integer values.

The behavior here appears to contradict the documentation (emphasis mine):

graphene.Enum uses enum.Enum internally (or a backport if that’s not available) and can be used in the exact same way.

IMHO, the correct behavior here would be for resolve_foo() to get Episode.NEWHOPE rather than 4 for the argument here, but this presumably would break a lot of existing code. Perhaps some sort of option to accomodate this?

Alternatively, having a graphene.IntEnum that's functionally equivalent to enum.IntEnum would be nice.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions