This issue tracker has been migrated to GitHub ,
and is currently read-only.
For more information,
see the GitHub FAQs in the Python's Developer Guide.
Created on 2013年05月11日 13:55 by ncoghlan, last changed 2022年04月11日 14:57 by admin. This issue is now closed.
| Messages (8) | |||
|---|---|---|---|
| msg188920 - (view) | Author: Alyssa Coghlan (ncoghlan) * (Python committer) | Date: 2013年05月11日 13:55 | |
Guido chose to follow Java in enforcing the invariant "Enum members are instances of that Enum" for PEP 435 (i.e. "assert (all(isinstance(x, SomeEnum) for x in SomeEnum)"). As a consequence, the Enum metaclass prevents subclassing of Enums with defined members. This is a reasonable design choice, but one that limits the applicability of the standard library enum solution for use cases that currently rely on this feature of a custom enum implementation (including flufl.enum, the original inspiration for this feature). An alternative reasonable design choice is to allow extension of enumerations (similar to flufl.enum) and relax the invariant to "Enum members are an instance of that Enum or an Enum-derived parent class of that Enum" (i.e. "assert (all(issubclass(type(x), Enum) and type(x) in SomeEnum.mro() for x in SomeEnum)") There is no need to support this directly in the standard library, but it would be valuable to make it straightforward to support in an Enum variant by subclassing the standard metaclass (similar to the customisation mechanisms provided to support things like autonumbered enums through a derived metaclass). Currently, implementing this behaviour involves overriding a private method of the metaclass (EnumMetaclass._get_mixins) |
|||
| msg188978 - (view) | Author: Ethan Furman (ethan.furman) * (Python committer) | Date: 2013年05月12日 05:42 | |
I'm sure this is a dumb question, but I have lots of them so thought I'd share. Can this issue be resolved simply by making the `_get_mixins` method `get_mixins`? |
|||
| msg188980 - (view) | Author: Alyssa Coghlan (ncoghlan) * (Python committer) | Date: 2013年05月12日 06:30 | |
I don't think that would be wise - there's currently other logic in _get_mixins that subclasses would then have to duplicate. I was thinking more of an allow_subclass() API that subtypes could override to always return True. EnumMeta would then just factor the relevant piece of _get_mixins out into the default allow_subclass implementation. |
|||
| msg188998 - (view) | Author: Alyssa Coghlan (ncoghlan) * (Python committer) | Date: 2013年05月12日 10:31 | |
I elaborated on this point in http://python-notes.boredomandlaziness.org/en/latest/python3/enum_creation.html#support-for-alternate-declaration-syntaxes However, I'm now wondering if the problem is simply that the "no extension of enums" rule is more restrictive than it needs to be. If you *don't define any new methods*, then there's no problem with extending an enumeration - it's only the combination of extension and adding extra behaviour which is incoherent. |
|||
| msg189015 - (view) | Author: Ethan Furman (ethan.furman) * (Python committer) | Date: 2013年05月12日 11:02 | |
Make it simpler: class EnumMeta(): allow_subclass = False class MyEnumMeta(EnumMeta): allow_subclass = True |
|||
| msg189025 - (view) | Author: Alyssa Coghlan (ncoghlan) * (Python committer) | Date: 2013年05月12日 12:52 | |
Simply removing the restriction isn't actually appropriate, as the variants that allow addition of new members should *not* allow addition of new descriptors. That's why I'm wondering if the current subclassing restriction is wrong: if you subclass an Enum derivative that already has defined members, then adding new members is OK, but adding new behaviour is not. If you subclass an Enum derivative with no members, then adding either members or behaviours is fine. If we relaxed the "no subclassing" rule to "no new non-members", then this Enums would be natively extensible and this customisation hack wouldn't be necessary at all. We have plenty of time before 3.4 - let's get the existing implementation in before worrying further about this. |
|||
| msg189030 - (view) | Author: Ethan Furman (ethan.furman) * (Python committer) | Date: 2013年05月12日 13:17 | |
Not trying to push, but if I don't write it down now, I'll forget later. ;) What does adding new members gain us? If I have a func xyz() that's expecting a Color, a MoreColor will work sometimes and blow up other times. Or are you saying that we may have a function mno() that takes a Color or a MoreColor? |
|||
| msg189032 - (view) | Author: Alyssa Coghlan (ncoghlan) * (Python committer) | Date: 2013年05月12日 13:32 | |
Ah, you're right, I forgot that was the other reason for disallowing extensions through subclassing. To get extensions to work right, you need to flip it around so that isinstance(Color.red, MoreColor) is True, while isinstance(MoreColor.magenta, Color) is False. |
|||
| History | |||
|---|---|---|---|
| Date | User | Action | Args |
| 2022年04月11日 14:57:45 | admin | set | github: 62154 |
| 2013年05月14日 03:56:30 | barry | set | nosy:
+ barry |
| 2013年05月12日 13:32:06 | ncoghlan | set | status: open -> closed resolution: not a bug dependencies: - Code, test, and doc review for PEP-0435 Enum messages: + msg189032 |
| 2013年05月12日 13:17:31 | ethan.furman | set | messages: + msg189030 |
| 2013年05月12日 12:52:34 | ncoghlan | set | messages: + msg189025 |
| 2013年05月12日 11:02:27 | ethan.furman | set | messages: + msg189015 |
| 2013年05月12日 10:31:23 | ncoghlan | set | messages: + msg188998 |
| 2013年05月12日 06:30:06 | ncoghlan | set | messages: + msg188980 |
| 2013年05月12日 05:42:15 | ethan.furman | set | nosy:
+ ethan.furman messages: + msg188978 |
| 2013年05月11日 13:55:45 | ncoghlan | set | dependencies: + Code, test, and doc review for PEP-0435 Enum |
| 2013年05月11日 13:55:34 | ncoghlan | create | |