[issue22339] Incorrect behavior when subclassing enum.Enum
Kiss György added the comment: Thanks for the tip! That looks much better. -- ___ Python tracker rep...@bugs.python.org http://bugs.python.org/issue22339 ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue22339] Incorrect behavior when subclassing enum.Enum
Kiss György added the comment: I found one thing which you can't do subclassing Enum what you can with metaclasses: enforcing type checking at class creation time. Values are passed to __new__ as positional arguments, so it's impossible to tell the difference between these two: class SingleValue(MultiVAlueEnum): one = 1, 'one' two = 2 class Tuple(MultiVAlueEnum): one = 1, 'one' two = 2, because in both cases (2,) would be passed. It's not a big deal, but Explicit is better than implicit. and also I would like to avoid typos, which I often make like this: class StrValues(MultiValueEnum): one = ('One' 'one') two = ('two', 'Two') In this case, the first member would be accepted as 'Oneone' instead of ('One', 'one') and I see no way to check that without metaclasses. Do you? -- ___ Python tracker rep...@bugs.python.org http://bugs.python.org/issue22339 ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue22339] Incorrect behavior when subclassing enum.Enum
Kiss György added the comment: Is this a way to easily handle multiple aliases? You mean this MultiValueEnum implementation? (If not I don't understand the question, could you elaborate?) No, this is the opposite of aliases, because an alias is when the same value have multiple names, but this is when the values are used to lookup the same name. I use it when very similar values have the same meaning like: class Suit(MultiValueEnum): CLUBS ='♣', 'c', 'C', 'clubs', 'club' DIAMONDS = '♦', 'd', 'D', 'diamonds', 'diamond' HEARTS = '♥', 'h', 'H', 'hearts', 'heart' SPADES = '♠', 's', 'S', 'spades', 'spade' Also it can be used for ECP testing (Equivalence class testing) like this: from http.client import responses class ResponseEnum(MultiValueEnum): GOOD = [status for status in responses if 200 = status = 299] BAD = [status for status in responses if not (200 = status = 299)] I did not think about this use case, but I think it's very interesting and useful. -- ___ Python tracker rep...@bugs.python.org http://bugs.python.org/issue22339 ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue22339] Incorrect behavior when subclassing enum.Enum
Kiss György added the comment: Oh, wow. I never really understood what _find_new_ did, now I do. I'm not sure what you are trying to accomplish there. Exactly that, I'm just not as good. Oh well at least I found a bug! :) Thanks for the enlightenment! If the patch goes in, I also would like one more minor change. On line 457, the missing value is represented as simple str(). In case of user defined types, it would make debugging easier if repr() would be used instead. I attached the patch. -- Added file: http://bugs.python.org/file36554/enum.patch2 ___ Python tracker rep...@bugs.python.org http://bugs.python.org/issue22339 ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue22339] Incorrect behavior when subclassing enum.Enum
New submission from Kiss György: There is a small inconvenience in the ``enum`` module. When I subclass ``enum.Enum`` and redefine the ``value`` dynamic attribute, the aliasing behavior doesn't work correctly, because ``member.value`` is used in some places instead of ``member._value_``. I attached a patch where I fixed all these places. This causes no harm to the internal working, but makes subclassing behave correctly. -- components: Library (Lib) files: enum.patch keywords: patch messages: 226392 nosy: Walkman priority: normal severity: normal status: open title: Incorrect behavior when subclassing enum.Enum type: enhancement versions: Python 3.4 Added file: http://bugs.python.org/file36543/enum.patch ___ Python tracker rep...@bugs.python.org http://bugs.python.org/issue22339 ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue22339] Incorrect behavior when subclassing enum.Enum
Kiss György added the comment: Yes, sorry I forgot about that. Here is a minimal example: from enum import EnumMeta, Enum from types import DynamicClassAttribute class _MultiMeta(EnumMeta): def __init__(enum_class, cls, bases, classdict): # make sure we only have tuple values, not single values for member in enum_class.__members__.values(): if not isinstance(member._value_, tuple): raise ValueError('{!r}, should be tuple'.format(member._value_)) def __call__(cls, suit): for member in cls: if suit in member._value_: return member return super().__call__(suit) class MultiValueEnum(Enum, metaclass=_MultiMeta): @DynamicClassAttribute def value(self): The value of the Enum member. return self._value_[0] class IncorrectAliasBehavior(MultiValueEnum): first = 1, 2, 3 second = 4, 5, 6 alias_to_first = 1, 2, 3 When you call IncorrectAliasBehavior.alias_to_first, the documentation says it should return IncorrectAliasBehavior.first, but in this case it returns IncorrectAliasBehavior.alias_to_first, because canonical_member.value is referenced on line 162, and so it returns the redefined value, not the internally used one. This was very confusing for me. -- ___ Python tracker rep...@bugs.python.org http://bugs.python.org/issue22339 ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com