Description
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.