django-enumfield icon indicating copy to clipboard operation
django-enumfield copied to clipboard

python 3.9.2 seems to break enumfields

Open jadedarko opened this issue 4 years ago • 2 comments

After upgrading to python 3.9.2 I am now unable to import from the enumfields package

3.9.2 changed the way subclassing and multiple inheritance works so it might be related?

Python 3.9.2 (default, Feb 20 2021, 20:59:40) 
[GCC 5.4.0 20160609] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from enumfields import EnumIntegerField
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/var/www/.venv/lib/python3.9/site-packages/enumfields/__init__.py", line 1, in <module>
    from .enums import Enum, IntEnum
  File "/var/www/.venv/lib/python3.9/site-packages/enumfields/enums.py", line 28, in <module>
    class Enum(EnumMeta('Enum', (BaseEnum,), _EnumDict())):
  File "/var/www/.venv/lib/python3.9/site-packages/enumfields/enums.py", line 18, in __new__
    obj = BaseEnumMeta.__new__(mcs, name, bases, attrs)
  File "/usr/lib/python3.9/enum.py", line 212, in __new__
    classdict['__doc__'] = 'An enumeration.'
  File "/usr/lib/python3.9/enum.py", line 97, in __setitem__
    if _is_private(self._cls_name, key):
AttributeError: '_EnumDict' object has no attribute '_cls_name'
>>> from enumfields import EnumField
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/var/www/.venv/lib/python3.9/site-packages/enumfields/__init__.py", line 1, in <module>
    from .enums import Enum, IntEnum
  File "/var/www/.venv/lib/python3.9/site-packages/enumfields/enums.py", line 28, in <module>
    class Enum(EnumMeta('Enum', (BaseEnum,), _EnumDict())):
  File "/var/www/.venv/lib/python3.9/site-packages/enumfields/enums.py", line 18, in __new__
    obj = BaseEnumMeta.__new__(mcs, name, bases, attrs)
  File "/usr/lib/python3.9/enum.py", line 212, in __new__
    classdict['__doc__'] = 'An enumeration.'
  File "/usr/lib/python3.9/enum.py", line 97, in __setitem__
    if _is_private(self._cls_name, key):
AttributeError: '_EnumDict' object has no attribute '_cls_name'
>>> import enumfields
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/var/www/.venv/lib/python3.9/site-packages/enumfields/__init__.py", line 1, in <module>
    from .enums import Enum, IntEnum
  File "/var/www/.venv/lib/python3.9/site-packages/enumfields/enums.py", line 28, in <module>
    class Enum(EnumMeta('Enum', (BaseEnum,), _EnumDict())):
  File "/var/www/.venv/lib/python3.9/site-packages/enumfields/enums.py", line 18, in __new__
    obj = BaseEnumMeta.__new__(mcs, name, bases, attrs)
  File "/usr/lib/python3.9/enum.py", line 212, in __new__
    classdict['__doc__'] = 'An enumeration.'
  File "/usr/lib/python3.9/enum.py", line 97, in __setitem__
    if _is_private(self._cls_name, key):
AttributeError: '_EnumDict' object has no attribute '_cls_name'

jadedarko avatar Mar 11 '21 23:03 jadedarko

From what I can tell, EnumMeta.__prepare__ doesn't seem to be used to generate the attrs dict enumfields uses

A hack to bypass this is to set attrs._cls_name to cls before invoking __new__, but that's obviously not ideal?

jadedarko avatar Mar 11 '21 23:03 jadedarko

ah, that's exactly what django-enumfields does:

https://github.com/hzdg/django-enumfields/commit/8a54ab6ca1a406b4f736b1d8a1daff49431a1c5c

Sorry for the noise, I'll swap to using that package.

jadedarko avatar Mar 12 '21 00:03 jadedarko

Closing this since it doesn't seem related to our package

Swamii avatar Feb 27 '23 10:02 Swamii