Issue 19025: Deleting attribute of Enum gives misleading error message (original) (raw)

Created on 2013-09-15 15:15 by vajrasky, last changed 2022-04-11 14:57 by admin. This issue is now closed.

Files
File name Uploaded Description Edit
handling_attribute_deletion_correctly_in_enum.patch vajrasky,2013-09-15 15:15 review
unit_test_attribute_deletion_enum.patch vajrasky,2013-09-16 04:40 review
Messages (7)
msg197775 - (view) Author: Vajrasky Kok (vajrasky) * Date: 2013-09-15 15:15
>>> from enum import Enum >>> class MyPet(Enum): ... CUTE_CAT = 1 ... VIGOROUS_DOG = 2 ... UGLY_BLOBFISH = 3 ... PROMISCUOUS_BONOBO = 4 ... def spam(cls): pass ... >>> del MyPet.CUTE_CAT Traceback (most recent call last): File "", line 1, in AttributeError: CUTE_CAT This is misleading. I have CUTE_CAT attribute in Enum. It should throw TypeError exception. >>> del MyPet.LONELY_WOLF Traceback (most recent call last): File "", line 1, in AttributeError: LONELY_WOLF This is correct. >>> del MyPet['CUTE_CAT'] Traceback (most recent call last): File "", line 1, in TypeError: 'EnumMeta' object does not support item deletion I think this behaviour is correct. >>> del MyPet['LONELY_WOLF'] Traceback (most recent call last): File "", line 1, in TypeError: 'EnumMeta' object does not support item deletion This behaviour is somewhat misleading. I don't have LONELY_WOLF item. >>> del MyPet.spam >>> hasattr(MyPet, 'spam') False This is correct. We should be able to delete method from Enum class, or shouldn't we? >>> cute_cat = MyPet.CUTE_CAT >>> del cute_cat.name Traceback (most recent call last): File "", line 1, in File "/home/sky/Code/python/programming_language/cpython/Lib/enum.py", line 29, in __delete__ raise AttributeError("can't delete attribute") AttributeError: can't delete attribute This is *maybe" correct. But shouldn't it be TypeError exception? All the exception messages related with deleting attribute in Python codebase are using TypeError exception (with one exception in pyexpat on which it uses RuntimeError exception). Attached the patch to handle the attribute deletion correctly. For now, I don't change the exception for the last case (del MyPet.CUTE_CAT.name) because maybe there is an exception case for enum.
msg197780 - (view) Author: R. David Murray (r.david.murray) * (Python committer) Date: 2013-09-15 16:04
Doesn't this confusion (here and in 19011) arise from the fact that the enum class does *not* have CUTE_CAT attribute? That is, the error message is correct, but surprising. Because, frankly, Enums are surprising in many ways ;)
msg197801 - (view) Author: Ethan Furman (ethan.furman) * (Python committer) Date: 2013-09-15 17:50
Perhaps a section in the docs about the differences from typical Python classes is warranted: - Enum members are virtual - Enum members are singletons - new Enum members (aka instances of an Enum class) cannot be created - during class creation Enum members cannot be overwritten, nor overwrite other class attributes - Enum classes with members cannot be subclassed - Enum classes support iteration - Enum classes support containment
msg197802 - (view) Author: Ethan Furman (ethan.furman) * (Python committer) Date: 2013-09-15 18:01
As for the error messages (going in reverse order): ========================================================================== --> del cute_cat.name Traceback (most recent call last): ... AttributeError: can't delete attribute ========================================================================== This is the same error given by @property. ========================================================================== --> del MyPet.spam --> hasattr(MyPet, 'spam') False ========================================================================== This is correct. Only Enum members get special treatment. ========================================================================== --> del MyPet['LONELY_WOLF'] Traceback (most recent call last): File "", line 1, in TypeError: 'EnumMeta' object does not support item deletion ========================================================================== There are two errors here: LONELY_WOLF does not exist, and an operation is being attempted that is not supported. Of those two, attempting the unsupported operation is the more serious, and should be the reported error. (Yes, dealing with multiple errors at once can often be confusing.) ========================================================================== --> del MyPet.CUTE_CAT Traceback (most recent call last): File "", line 1, in AttributeError: CUTE_CAT ========================================================================== This one I am not sure about (much as I am not sure about __getattr__ in #19011). Enum members are virtual, and don't actually live in the class namespace. I'm inclined to leave the existing behavior as is, but if we choose to change one, we should change both.
msg197868 - (view) Author: Vajrasky Kok (vajrasky) * Date: 2013-09-16 04:40
Here is the patch containing unit test only to confirm existing behaviour. So people can learn what to expect when they delete Enum attributes. Even if we *decide* to change the behaviour of "del MyPet.CUTE_CAT" (assuming CUTE_CAT is an Enum member), I sense that we would only change the exception message not the exception type. That is, it still throws AttributeError but with better error message, such as "Cannot delete attribute."
msg198307 - (view) Author: Ethan Furman (ethan.furman) * (Python committer) Date: 2013-09-22 23:15
Okay, I changed my mind about __delattr__. Having it say "AttributeError: cannot delete Enum member" is certainly nicer than "AttributeError: MemberName"
msg198308 - (view) Author: Roundup Robot (python-dev) (Python triager) Date: 2013-09-22 23:18
New changeset ed011b0d7daf by Ethan Furman in branch 'default': Close #19025: Better error message when trying to delete an Enum member. http://hg.python.org/cpython/rev/ed011b0d7daf
History
Date User Action Args
2022-04-11 14:57:50 admin set github: 63225
2013-09-22 23🔞38 python-dev set status: open -> closednosy: + python-devmessages: + resolution: fixedstage: resolved
2013-09-22 23:15:07 ethan.furman set messages: +
2013-09-16 04:40:08 vajrasky set files: + unit_test_attribute_deletion_enum.patchmessages: +
2013-09-15 18:01:03 ethan.furman set messages: +
2013-09-15 17:50:38 ethan.furman set nosy: + eli.benderskymessages: +
2013-09-15 16:34:11 ethan.furman set assignee: ethan.furman
2013-09-15 16:28:00 barry set nosy: + barry
2013-09-15 16:04:30 r.david.murray set nosy: + r.david.murraymessages: +
2013-09-15 15:15:10 vajrasky create