mirror of
https://github.com/graphql-python/graphene.git
synced 2025-02-09 08:00:39 +03:00
Merge pull request #586 from ekampf/feature/enum_value_descriptions
Support from_enum description lambda
This commit is contained in:
commit
f79eb57c06
|
@ -21,6 +21,7 @@ EnumType = type(PyEnum)
|
||||||
|
|
||||||
class EnumOptions(BaseOptions):
|
class EnumOptions(BaseOptions):
|
||||||
enum = None # type: Enum
|
enum = None # type: Enum
|
||||||
|
deprecation_reason = None
|
||||||
|
|
||||||
|
|
||||||
class EnumMeta(SubclassWithMeta_Meta):
|
class EnumMeta(SubclassWithMeta_Meta):
|
||||||
|
@ -45,8 +46,14 @@ class EnumMeta(SubclassWithMeta_Meta):
|
||||||
return super(EnumMeta, cls).__call__(*args, **kwargs)
|
return super(EnumMeta, cls).__call__(*args, **kwargs)
|
||||||
# return cls._meta.enum(*args, **kwargs)
|
# return cls._meta.enum(*args, **kwargs)
|
||||||
|
|
||||||
def from_enum(cls, enum, description=None): # noqa: N805
|
def from_enum(cls, enum, description=None, deprecation_reason=None): # noqa: N805
|
||||||
meta_class = type('Meta', (object,), {'enum': enum, 'description': description})
|
description = description or enum.__doc__
|
||||||
|
meta_dict = {
|
||||||
|
'enum': enum,
|
||||||
|
'description': description,
|
||||||
|
'deprecation_reason': deprecation_reason
|
||||||
|
}
|
||||||
|
meta_class = type('Meta', (object,), meta_dict)
|
||||||
return type(meta_class.enum.__name__, (Enum,), {'Meta': meta_class})
|
return type(meta_class.enum.__name__, (Enum,), {'Meta': meta_class})
|
||||||
|
|
||||||
|
|
||||||
|
@ -56,8 +63,10 @@ class Enum(six.with_metaclass(EnumMeta, UnmountedType, BaseType)):
|
||||||
def __init_subclass_with_meta__(cls, enum=None, **options):
|
def __init_subclass_with_meta__(cls, enum=None, **options):
|
||||||
_meta = EnumOptions(cls)
|
_meta = EnumOptions(cls)
|
||||||
_meta.enum = enum or cls.__enum__
|
_meta.enum = enum or cls.__enum__
|
||||||
|
_meta.deprecation_reason = options.pop('deprecation_reason', None)
|
||||||
for key, value in _meta.enum.__members__.items():
|
for key, value in _meta.enum.__members__.items():
|
||||||
setattr(cls, key, value)
|
setattr(cls, key, value)
|
||||||
|
|
||||||
super(Enum, cls).__init_subclass_with_meta__(_meta=_meta, **options)
|
super(Enum, cls).__init_subclass_with_meta__(_meta=_meta, **options)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
import six
|
||||||
|
|
||||||
|
from ..schema import Schema, ObjectType
|
||||||
from ..argument import Argument
|
from ..argument import Argument
|
||||||
from ..enum import Enum, PyEnum
|
from ..enum import Enum, PyEnum
|
||||||
from ..field import Field
|
from ..field import Field
|
||||||
|
@ -66,6 +69,57 @@ def test_enum_from_builtin_enum():
|
||||||
assert RGB.BLUE
|
assert RGB.BLUE
|
||||||
|
|
||||||
|
|
||||||
|
def test_enum_from_builtin_enum_accepts_lambda_description():
|
||||||
|
def custom_description(value):
|
||||||
|
if not value:
|
||||||
|
return "StarWars Episodes"
|
||||||
|
|
||||||
|
return 'New Hope Episode' if value == Episode.NEWHOPE else 'Other'
|
||||||
|
|
||||||
|
def custom_deprecation_reason(value):
|
||||||
|
return 'meh' if value == Episode.NEWHOPE else None
|
||||||
|
|
||||||
|
PyEpisode = PyEnum('PyEpisode', 'NEWHOPE,EMPIRE,JEDI')
|
||||||
|
Episode = Enum.from_enum(PyEpisode, description=custom_description, deprecation_reason=custom_deprecation_reason)
|
||||||
|
|
||||||
|
class Query(ObjectType):
|
||||||
|
foo = Episode()
|
||||||
|
|
||||||
|
schema = Schema(query=Query)
|
||||||
|
|
||||||
|
GraphQLPyEpisode = schema._type_map['PyEpisode'].values
|
||||||
|
|
||||||
|
assert schema._type_map['PyEpisode'].description == "StarWars Episodes"
|
||||||
|
assert GraphQLPyEpisode[0].name == 'NEWHOPE' and GraphQLPyEpisode[0].description == 'New Hope Episode'
|
||||||
|
assert GraphQLPyEpisode[1].name == 'EMPIRE' and GraphQLPyEpisode[1].description == 'Other'
|
||||||
|
assert GraphQLPyEpisode[2].name == 'JEDI' and GraphQLPyEpisode[2].description == 'Other'
|
||||||
|
|
||||||
|
assert GraphQLPyEpisode[0].name == 'NEWHOPE' and GraphQLPyEpisode[0].deprecation_reason == 'meh'
|
||||||
|
assert GraphQLPyEpisode[1].name == 'EMPIRE' and GraphQLPyEpisode[1].deprecation_reason == None
|
||||||
|
assert GraphQLPyEpisode[2].name == 'JEDI' and GraphQLPyEpisode[2].deprecation_reason == None
|
||||||
|
|
||||||
|
|
||||||
|
def test_enum_from_python3_enum_uses_enum_doc():
|
||||||
|
if not six.PY3:
|
||||||
|
return
|
||||||
|
|
||||||
|
from enum import Enum as PyEnum
|
||||||
|
|
||||||
|
class Color(PyEnum):
|
||||||
|
"""This is the description"""
|
||||||
|
RED = 1
|
||||||
|
GREEN = 2
|
||||||
|
BLUE = 3
|
||||||
|
|
||||||
|
RGB = Enum.from_enum(Color)
|
||||||
|
assert RGB._meta.enum == Color
|
||||||
|
assert RGB._meta.description == "This is the description"
|
||||||
|
assert RGB
|
||||||
|
assert RGB.RED
|
||||||
|
assert RGB.GREEN
|
||||||
|
assert RGB.BLUE
|
||||||
|
|
||||||
|
|
||||||
def test_enum_value_from_class():
|
def test_enum_value_from_class():
|
||||||
class RGB(Enum):
|
class RGB(Enum):
|
||||||
RED = 1
|
RED = 1
|
||||||
|
|
|
@ -127,16 +127,27 @@ class TypeMap(GraphQLTypeMap):
|
||||||
def construct_enum(self, map, type):
|
def construct_enum(self, map, type):
|
||||||
values = OrderedDict()
|
values = OrderedDict()
|
||||||
for name, value in type._meta.enum.__members__.items():
|
for name, value in type._meta.enum.__members__.items():
|
||||||
|
description = getattr(value, 'description', None)
|
||||||
|
deprecation_reason = getattr(value, 'deprecation_reason', None)
|
||||||
|
if not description and callable(type._meta.description):
|
||||||
|
description = type._meta.description(value)
|
||||||
|
|
||||||
|
if not deprecation_reason and callable(type._meta.deprecation_reason):
|
||||||
|
deprecation_reason = type._meta.deprecation_reason(value)
|
||||||
|
|
||||||
values[name] = GraphQLEnumValue(
|
values[name] = GraphQLEnumValue(
|
||||||
name=name,
|
name=name,
|
||||||
value=value.value,
|
value=value.value,
|
||||||
description=getattr(value, 'description', None),
|
description=description,
|
||||||
deprecation_reason=getattr(value, 'deprecation_reason', None))
|
deprecation_reason=deprecation_reason)
|
||||||
|
|
||||||
|
type_description = type._meta.description(None) if callable(type._meta.description) else type._meta.description
|
||||||
|
|
||||||
return GrapheneEnumType(
|
return GrapheneEnumType(
|
||||||
graphene_type=type,
|
graphene_type=type,
|
||||||
values=values,
|
values=values,
|
||||||
name=type._meta.name,
|
name=type._meta.name,
|
||||||
description=type._meta.description, )
|
description=type_description, )
|
||||||
|
|
||||||
def construct_objecttype(self, map, type):
|
def construct_objecttype(self, map, type):
|
||||||
if type._meta.name in map:
|
if type._meta.name in map:
|
||||||
|
|
Loading…
Reference in New Issue
Block a user