Skip to content

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

Closed
@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

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions