Repository: graphql-python/graphene

Issue:
cannot have Enum member named "description"
if the enum contains member called "descrpition" or "deprecation_reason", graphql schema-bullding validations die with error like :
TypeError: The description of the enum value must be a string

Happens on latest beta version, and depends on grapql's version.

This seems because in create_enum() (former construct_enum()) , the enumeration `__members__` values are being getattr for description and deprecation_reason.. hoping to get those metadata if passed intially. But python Enum members are very strange beasts and dont work correctly with getattr:

`>>> e=enum.Enum('aa', dict(a=1, b=2, description=5))`
`>>> e`
`<enum 'aa'>`
`>>> e.a`
`<aa.a: 1>`
`>>> e.a.description`
`<aa.description: 5>`
`>>> e.a.description.b`
`<aa.b: 2>`

So essentialy, they are a kind of proxy to the enum itself.
So getattr( enummembervalue, "description", None) will return None if there is no member called description, but will return that member if it exists, and later the graphql.GraphQLEnumValue() constructor raises TypeError.. (Which seems relatively recent validation).

The correct way is enummembervalue.value:

`>>> e.a.value`
1
`>>> e.a.value.description`
`Traceback (most recent call last):`
`  File "<stdin>", line 1, in <module>`
`AttributeError: 'int' object has no attribute 'description'`

ciao


Discussion:
codecov[bot]: # [Codecov](https://codecov.io/gh/graphql-python/graphene/pull/1478?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=graphql-python) Report
Base: **95.88**% // Head: **95.95**% // Increases project coverage by **`+0.06%`** :tada:
> Coverage data is based on head [(`a8eccee`)](https://codecov.io/gh/graphql-python/graphene/pull/1478?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=graphql-python) compared to base [(`ccdd35b`)](https://codecov.io/gh/graphql-python/graphene/commit/ccdd35b354007c3899a7b62ffe132414ee226fec?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=graphql-python).
> Patch coverage: 100.00% of modified lines in pull request are covered.

<details><summary>Additional details and impacted files</summary>


```diff
@@            Coverage Diff             @@
##           master    #1478      +/-   ##
==========================================
+ Coverage   95.88%   95.95%   +0.06%     
==========================================
  Files          50       50              
  Lines        1724     1729       +5     
==========================================
+ Hits         1653     1659       +6     
+ Misses         71       70       -1     
```


| [Impacted Files](https://codecov.io/gh/graphql-python/graphene/pull/1478?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=graphql-python) | Coverage Δ | |
|---|---|---|
| [graphene/validation/depth\_limit.py](https://codecov.io/gh/graphql-python/graphene/pull/1478/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=graphql-python#diff-Z3JhcGhlbmUvdmFsaWRhdGlvbi9kZXB0aF9saW1pdC5weQ==) | `96.96% <ø> (ø)` | |
| [graphene/test/\_\_init\_\_.py](https://codecov.io/gh/graphql-python/graphene/pull/1478/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=graphql-python#diff-Z3JhcGhlbmUvdGVzdC9fX2luaXRfXy5weQ==) | `85.18% <100.00%> (+3.70%)` | :arrow_up: |
| [graphene/types/enum.py](https://codecov.io/gh/graphql-python/graphene/pull/1478/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=graphql-python#diff-Z3JhcGhlbmUvdHlwZXMvZW51bS5weQ==) | `100.00% <100.00%> (ø)` | |
| [graphene/types/inputobjecttype.py](https://codecov.io/gh/graphql-python/graphene/pull/1478/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=graphql-python#diff-Z3JhcGhlbmUvdHlwZXMvaW5wdXRvYmplY3R0eXBlLnB5) | `97.29% <100.00%> (ø)` | |
| [graphene/types/schema.py](https://codecov.io/gh/graphql-python/graphene/pull/1478/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=graphql-python#diff-Z3JhcGhlbmUvdHlwZXMvc2NoZW1hLnB5) | `95.37% <100.00%> (+0.05%)` | :arrow_up: |

Help us with your feedback. Take ten seconds to tell us [how you rate us](https://about.codecov.io/nps?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=graphql-python). Have a feature suggestion? [Share it here.](https://app.codecov.io/gh/feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=graphql-python)

</details>

[:umbrella: View full report at Codecov](https://codecov.io/gh/graphql-python/graphene/pull/1478?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=graphql-python).   
:loudspeaker: Do you have feedback about the report comment? [Let us know in this issue](https://about.codecov.io/codecov-pr-comment-feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=graphql-python).

erikwrede: This might help users that need to define an enum member called description in their schema. 
I agree that this is not an ideal solution. Maybe looking into supporting `aenum` for this special case using a special enum type could be an option? 
Other than that, it looks like we can't do much about this issue without making breaking changes to `graphene.Enum` like defining custom enum members that have a `description` field.
mike-roberts-healx: > This might help users that need to define an enum member called description in their schema. I agree that this is not an ideal solution. Maybe looking into supporting `aenum` for this special case using a special enum type could be an option? Other than that, it looks like we can't do much about this issue without making breaking changes to `graphene.Enum` like defining custom enum members that have a `description` field.

Yeah, we are hitting this issue in one of our graphQL APIs. It auto-generates a schema at initialisation time from the database schema, which has elements named "description". I've worked around it for now by registering `Enum` as a valid type for enum descriptions but that is really an ugly hack.
mike-roberts-healx: I can't think of an elegant solution that keeps descriptions working the way they currently do while also allowing for Enum members called "description" to have descriptions. 

This PR is a fairly conservative change in that it shouldn't break any existing functionality, but fixes the case where there is an Enum with a member called "description" that doesn't have a description.

Patch:
diff --git a/graphene/types/schema.py b/graphene/types/schema.py
index 1a33a93..7fa046d 100644
--- a/graphene/types/schema.py
+++ b/graphene/types/schema.py
@@ -1,3 +1,4 @@
+from enum import Enum as PyEnum
 import inspect
 from functools import partial
 
@@ -169,10 +170,16 @@ class TypeMap(dict):
         values = {}
         for name, value in graphene_type._meta.enum.__members__.items():
             description = getattr(value, "description", None)
-            deprecation_reason = getattr(value, "deprecation_reason", None)
+            # if the "description" attribute is an Enum, it is likely an enum member
+            # called description, not a description property
+            if isinstance(description, PyEnum):
+                description = None
             if not description and callable(graphene_type._meta.description):
                 description = graphene_type._meta.description(value)
 
+            deprecation_reason = getattr(value, "deprecation_reason", None)
+            if isinstance(deprecation_reason, PyEnum):
+                deprecation_reason = None
             if not deprecation_reason and callable(
                 graphene_type._meta.deprecation_reason
             ):


Test patch:
diff --git a/graphene/types/tests/test_enum.py b/graphene/types/tests/test_enum.py
index 298cc23..9b3082d 100644
--- a/graphene/types/tests/test_enum.py
+++ b/graphene/types/tests/test_enum.py
@@ -565,3 +565,36 @@ def test_iterable_instance_creation_enum():
     for c in TestEnum:
         result.append(c.name)
     assert result == expected_values
+
+
+# https://github.com/graphql-python/graphene/issues/1321
+def test_enum_description_member_not_interpreted_as_property():
+    class RGB(Enum):
+        """Description"""
+
+        red = "red"
+        green = "green"
+        blue = "blue"
+        description = "description"
+        deprecation_reason = "deprecation_reason"
+
+    class Query(ObjectType):
+        color = RGB()
+
+        def resolve_color(_, info):
+            return RGB.description
+
+    values = RGB._meta.enum.__members__.values()
+    assert sorted(v.name for v in values) == [
+        "blue",
+        "deprecation_reason",
+        "description",
+        "green",
+        "red",
+    ]
+
+    schema = Schema(query=Query)
+
+    results = schema.execute("query { color }")
+    assert not results.errors
+    assert results.data["color"] == RGB.description.name