-
Notifications
You must be signed in to change notification settings - Fork 820
Closed
Labels
Description
This is for graphene 2.1.3.
There are a bunch of issues working with enums, here are two that bite me right now:
- When specifying
default_value
, we need to explicitly add.name
or.value
, else introspection breaks (see commented out code).
- If specifying
.value
, the schema generated is wrong (See test 1 below). - If specifying
.name
, the schema is correct, but the argument passed to the function is a string that doesn't match any value (See test 1 and 2).
- When working with python-backed enums, the value passed to the resolver doesn't match any sensible value (See test 3, below).
Test code:
#! /usr/bin/env python
import graphene
import json
import enum
class Episode(graphene.Enum):
NEWHOPE = 4
EMPIRE = 5
JEDI = 6
class BackendLengthUnit(enum.Enum):
METER = 'm'
FOOT = 'f'
LengthUnit = graphene.Enum.from_enum(BackendLengthUnit)
class Query(graphene.ObjectType):
# desc = graphene.String(
# v=graphene.Argument(Episode, default_value=Episode.NEWHOPE),
# description='See ./broken-schema.py')
desc1 = graphene.String(
v=graphene.Argument(Episode, default_value=Episode.NEWHOPE.value),
description='default value in schema is `4`, which is not valid. Also, awkward to write.')
desc2 = graphene.String(
v=graphene.Argument(Episode, default_value=Episode.NEWHOPE.name),
description='Default value is correct in schema doc. awkward to write.')
pyenum = graphene.String(
v=graphene.Argument(LengthUnit),
description='More fun with python-enum backed enum.')
def resolve_desc1(self, info, v):
return f'argument: {v!r}'
def resolve_desc2(self, info, v):
return f'argument: {v!r}'
def resolve_pyenum(self, info, v):
return (
f'Argument: {v!r}. '
f'Is GrapheneEnum foot: {v == LengthUnit.FOOT}. '
f'Is Backend enum foot: {v == BackendLengthUnit.FOOT}. '
)
schema = graphene.Schema(query=Query)
print('*** Schema:')
print(schema)
def qp(query):
print(json.dumps(schema.execute(query).data, indent=2))
def qpf(query):
print(json.dumps(schema.execute(query).to_dict(), indent=2))
print('*** Test 1: use default values:')
qp('{desc1, desc2}')
# Should be:
# {
# "desc1": "argument: <EnumMeta.NEWHOPE: 4>", (enum value)
# "desc2": "argument: <EnumMeta.NEWHOPE: 4>"
# }
# but actually is:
# {
# "desc1": "argument: 4", (int value)
# "desc2": "argument: 'NEWHOPE'" (string name)
# }
print('*** Test 2: Providing a value:')
qp('{desc1(v: JEDI), desc2(v: JEDI)}')
# Should be:
# {
# "desc1": "argument: <EnumMeta.JEDI: 6>", (enum value)
# "desc2": "argument: <EnumMeta.JEDI: 6>"
# }
# but actually is:
# {
# "desc1": "argument: 6",
# "desc2": "argument: 6"
# }
print('*** Test 3: Working with Python Enums:')
qp('{pyenum(v: FOOT)}')
# This is what we get:
# {
# "pyenum": "Argument: 'f'. Is GrapheneEnum foot: False. Is Backend enum foot: False. "
# }
# In order to be useful, it should be at least one of these things!
tdiam, ZelimDamian, squarewave24 and joefreeman