classification
Title: Enum doesn't allow name
Type: behavior Stage: resolved
Components: Library (Lib) Versions: Python 3.7, Python 3.6
process
Status: closed Resolution: third party
Dependencies: Superseder:
Assigned To: Nosy List: Robert Gomułka, barry, eli.bendersky, ethan.furman
Priority: normal Keywords:

Created on 2017-09-26 06:58 by Robert Gomułka, last changed 2017-09-26 09:52 by Robert Gomułka. This issue is now closed.

Messages (3)
msg303017 - (view) Author: Robert Gomułka (Robert Gomułka) Date: 2017-09-26 06:58
Enum module handles "name" member incorrectly.
1. "name" can't be used as a member when decorated with unique:

>>> import enum
>>> @enum.unique
... class A(enum.IntEnum):
...     a = 1
...     name = 2
...
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
  File "C:\Python27\Lib\site-packages\enum\__init__.py", line 835, in unique
    (enumeration, duplicate_names)
ValueError: duplicate names found in <enum 'A'>: a -> A.name, name -> A.name

2. Without unique the names are assigned incorrectly:

>>> class A(enum.IntEnum):
...     a = 1
...     name = 2
...
>>> A.__members__['a'].name
<A.name: 2>
>>> A.__members__['name'].name
<A.name: 2>

(Just for reference - spotted first on Python 2.7 + enum34 backports)

The same happens for value property, making the bug quite severe:

>>> class A(enum.IntEnum):
...     a = 1
...     value = 3
...
>>> A.__members__['a'].value
<A.value: 3>
>>> A.__members__['value'].value
<A.value: 3>

I believe this comment is related:
# _RouteClassAttributeToGetattr is used to provide access to the `name`
# and `value` properties of enum members while keeping some measure of
# protection from modification, while still allowing for an enumeration
# to have members named `name` and `value`.  This works because enumeration
# members are not set directly on the enum class -- __getattr__ is
# used to look them up.


Platform: Python 3.6.2 (v3.6.2:5fd33b5, Jul  8 2017, 04:14:34) [MSC v.1900 32 bit (Intel)] on win32
msg303018 - (view) Author: Robert Gomułka (Robert Gomułka) Date: 2017-09-26 07:06
As a workaround, one can:
1. Rename the fields to not use name/value names
2. Use Enum instead of IntEnum, which somehow doesn't have this bug.
msg303027 - (view) Author: Robert Gomułka (Robert Gomułka) Date: 2017-09-26 09:52
It turns out that enum34 backports module was the culprit (it was first on search path). When using enum native module, everything works as expected:

> c:\Python\Python36-32\python.exe -I
Python 3.6.2 (v3.6.2:5fd33b5, Jul  8 2017, 04:14:34) [MSC v.1900 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import enum
>>> enum
<module 'enum' from 'c:\\Python\\Python36-32\\lib\\enum.py'>
>>> @enum.unique
... class A(enum.IntEnum):
...     a = 1
...     name = 2
...     value = 3
...
>>> exit()

> c:\Python\Python36-32\python.exe
Python 3.6.2 (v3.6.2:5fd33b5, Jul  8 2017, 04:14:34) [MSC v.1900 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import enum
>>> enum
<module 'enum' from 'C:\\Python27\\Lib\\site-packages\\enum\\__init__.py'>
>>> @enum.unique
... class A(enum.IntEnum):
...     a = 1
...     name = 2
...     value = 3
...
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
  File "C:\Python27\Lib\site-packages\enum\__init__.py", line 835, in unique
    (enumeration, duplicate_names)
ValueError: duplicate names found in <enum 'A'>: a -> A.name, name -> A.name, value -> A.name

Sorry for the noise.
History
Date User Action Args
2017-09-26 09:52:05Robert Gomułkasetstatus: open -> closed
resolution: third party
messages: + msg303027

stage: resolved
2017-09-26 07:06:45Robert Gomułkasetmessages: + msg303018
2017-09-26 07:01:01serhiy.storchakasetnosy: + barry, eli.bendersky, ethan.furman

versions: + Python 3.7
2017-09-26 06:58:17Robert Gomułkacreate