From 5e050a6800e8cd7ca1095cbbf08c410aeabc3fea Mon Sep 17 00:00:00 2001 From: mykyta Date: Sat, 11 Sep 2021 11:10:02 +0300 Subject: [PATCH 1/4] add failing test for enum inheritance --- graphene/types/tests/test_enum.py | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/graphene/types/tests/test_enum.py b/graphene/types/tests/test_enum.py index 6e204aa9c..0c00df115 100644 --- a/graphene/types/tests/test_enum.py +++ b/graphene/types/tests/test_enum.py @@ -471,3 +471,31 @@ class Query(ObjectType): assert result.data == {"createPaint": {"color": "RED"}} assert color_input_value == RGB.RED + + +def test_enum_inheritance(): + class ParentRGB(Enum): + RED = 1 + + class ChildRGB(ParentRGB, Enum): + BLUE = 2 + + class Query(ObjectType): + color = ChildRGB(required=True) + + def resolve_color(_, info): + return ChildRGB.RED + + schema = Schema(query=Query) + assert str(schema) == dedent( + '''\ + type Query { + color: ChildRGB! + } + + enum ChildRGB { + RED + BLUE + } + ''' + ) From ba6b46088bca91f34e8c24fe8e54a359243733f4 Mon Sep 17 00:00:00 2001 From: mykyta Date: Sat, 11 Sep 2021 12:56:16 +0300 Subject: [PATCH 2/4] update EnumOptions and EnumMeta to support inheritance --- graphene/types/enum.py | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/graphene/types/enum.py b/graphene/types/enum.py index 70e8ee8e0..2bba903e8 100644 --- a/graphene/types/enum.py +++ b/graphene/types/enum.py @@ -1,4 +1,5 @@ from enum import Enum as PyEnum +from typing import Iterable, Type, Optional from graphene.utils.subclass_with_meta import SubclassWithMeta_Meta @@ -18,11 +19,18 @@ def eq_enum(self, other): class EnumOptions(BaseOptions): enum = None # type: Enum deprecation_reason = None + enums = () # type: Iterable[Type[Enum]] class EnumMeta(SubclassWithMeta_Meta): def __new__(cls, name_, bases, classdict, **options): - enum_members = dict(classdict, __eq__=eq_enum) + enum_members = dict(__eq__=eq_enum) + meta = classdict.get("Meta", None) # type: Optional[EnumOptions] + if meta and hasattr(meta, 'enums'): + for enum in meta.enums: + enum_members.update(enum.as_dict()) + enum_members.update(classdict) + # We remove the Meta attribute from the class to not collide # with the enum values. enum_members.pop("Meta", None) @@ -106,3 +114,10 @@ def get_type(cls): is mounted (as a Field, InputField or Argument) """ return cls + + @classmethod + def as_dict(cls): + return { + enum_meta.name: enum_meta.value + for _, enum_meta in cls._meta.enum.__members__.items() + } From b7404ecf8138a9fe077ba2095f12922d5909a611 Mon Sep 17 00:00:00 2001 From: mykyta Date: Sat, 11 Sep 2021 12:56:30 +0300 Subject: [PATCH 3/4] update test to use new EnumOptions --- graphene/types/tests/test_enum.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/graphene/types/tests/test_enum.py b/graphene/types/tests/test_enum.py index 0c00df115..0663784d9 100644 --- a/graphene/types/tests/test_enum.py +++ b/graphene/types/tests/test_enum.py @@ -477,9 +477,12 @@ def test_enum_inheritance(): class ParentRGB(Enum): RED = 1 - class ChildRGB(ParentRGB, Enum): + class ChildRGB(Enum): BLUE = 2 + class Meta: + enums = (ParentRGB,) + class Query(ObjectType): color = ChildRGB(required=True) From cc1e60c9118df62be00c72f19ba7acb7e23fcb17 Mon Sep 17 00:00:00 2001 From: mykyta Date: Sat, 11 Sep 2021 13:05:17 +0300 Subject: [PATCH 4/4] add some more complicated tests --- graphene/types/tests/test_enum.py | 47 +++++++++++++++++++++++++++++-- 1 file changed, 45 insertions(+), 2 deletions(-) diff --git a/graphene/types/tests/test_enum.py b/graphene/types/tests/test_enum.py index 0663784d9..b5448cd6c 100644 --- a/graphene/types/tests/test_enum.py +++ b/graphene/types/tests/test_enum.py @@ -486,8 +486,36 @@ class Meta: class Query(ObjectType): color = ChildRGB(required=True) - def resolve_color(_, info): - return ChildRGB.RED + schema = Schema(query=Query) + assert str(schema) == dedent( + '''\ + type Query { + color: ChildRGB! + } + + enum ChildRGB { + RED + BLUE + } + ''' + ) + + +def test_multiple_enum_inheritance(): + class Parent1RGB(Enum): + RED = 1 + + class Parent2RGB(Enum): + BLUE = 2 + + class ChildRGB(Enum): + GREEN = 3 + + class Meta: + enums = (Parent1RGB, Parent2RGB,) + + class Query(ObjectType): + color = ChildRGB(required=True) schema = Schema(query=Query) assert str(schema) == dedent( @@ -499,6 +527,21 @@ def resolve_color(_, info): enum ChildRGB { RED BLUE + GREEN } ''' ) + + +def test_override_enum_inheritance(): + class ParentRGB(Enum): + RED = 1 + BLUE = 2 + + class ChildRGB(Enum): + BLUE = 3 + + class Meta: + enums = (ParentRGB,) + + assert ChildRGB.get(3) != ParentRGB.BLUE