homepage

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.

classification
Title: Alternate approach to aliasing for PEP 435
Type: enhancement Stage: resolved
Components: Versions: Python 3.4
process
Status: closed Resolution: rejected
Dependencies: Superseder:
Assigned To: Nosy List: alex, barry, dilettant, eric.smith, ethan.furman, gvanrossum, ncoghlan, pitrou
Priority: high Keywords:

Created on 2013年05月12日 06:51 by ncoghlan, last changed 2022年04月11日 14:57 by admin. This issue is now closed.

Messages (12)
msg188981 - (view) Author: Alyssa Coghlan (ncoghlan) * (Python committer) Date: 2013年05月12日 06:51
Creating this as a separate issue so as not to delay incorporation of the accepted PEP.
One legitimate criticism of the accepted PEP 435 is that the combination of requiring explicit assignment of values *and* allowing aliasing by default is that aliases may be created inadvertently. I believe we can actually do better than the initial implementation by making the following work:
>>> class Shape(Enum):
... square = 2
... diamond = 1
... circle = 3
... alias_for_square = square
...
>>> Shape.square
<Shape.square: 2>
>>> Shape.alias_for_square
<Shape.square: 2>
>>> Shape(2)
<Shape.square: 2>
While *disallowing* the following: 
>>> class Shape(Enum):
... square = 2
... diamond = 1
... circle = 3
... alias_for_square = 2
...
How, do you ask? By wrapping non-descriptors on assignment in a placeholder type, and keeping track of which values we have already seen. If a new attribute is mapped to a placeholder, then that's fine, we accept it as an explicit declaration of an alias. However, if it's mapped directly to a repeat value, then that would be disallowed (as it was in earlier versions of the PEP).
msg188983 - (view) Author: Alex Gaynor (alex) * (Python committer) Date: 2013年05月12日 06:54
This would preclude code like:
class Shape(Enum):
 rectangle = shape = 2
which seems (to me) to be the most reasonable way to express aliasing.
msg188988 - (view) Author: Alyssa Coghlan (ncoghlan) * (Python committer) Date: 2013年05月12日 07:56
That's a terrible way to express aliasing, because it's really unclear that "rectangle" is the canonical name.
By contrast:
 class Shape(Enum):
 rectangle = 2
 oblong = rectangle
leaves no doubt as to which is canonical and which is the alias. You never need to go beyond two assignments, as you can still use multiple target assignment for the aliases.
msg189008 - (view) Author: Ethan Furman (ethan.furman) * (Python committer) Date: 2013年05月12日 10:44
Another approach to handling this, and other, issues is to allow options to EnumMeta. My original aenum code had the default Enum class as unordered, no duplicates allowed, non-indexable, etc., but then allowed options to be passed in such as DUPLICATES to allow duplicates, ORDERED to add the ge-gt-le-lt methods, INDEXED to add __index__, etc.
For the aliasing issue this method is more robust as placeholders are not required, and code like this will work:
class Physics(Enum):
 e = 2.81847
 pi = 3.141596
 tau = 2 * pi
To make that code work with placeholders is possible (I have it in aenum) but a major pain (I was about to remove it before my offer to help with ref435 was accepted).
msg189024 - (view) Author: Alyssa Coghlan (ncoghlan) * (Python committer) Date: 2013年05月12日 12:44
Hmm, that's an interesting point about allowing operations on the already defined values.
You could get around that by requiring that the wrapper be explicit when definined the alias:
>>> class Shape(enum.Enum):
... rectangle = 1
... oblong = enum.alias(rectangle)
Or, equivalently:
>>> class Shape(enum.Enum):
... rectangle = 1
... oblong = enum.alias(1)
So simple typos would trigger an error by default, and the enum.alias wrapper would tell the namespace (or the metaclass) "hey, this should be an alias for another value already defined here".
I definitely don't want us to turn the metaclass into a swiss army knife of behavioural options - I'm happy with customisation hooks in the metaclass on that front, as I believe it is an effective way to discourage excessive use of metaclass magic without preventing it when it is necessary.
msg189042 - (view) Author: Antoine Pitrou (pitrou) * (Python committer) Date: 2013年05月12日 16:12
That's way too much magic for my taste.
msg189043 - (view) Author: Antoine Pitrou (pitrou) * (Python committer) Date: 2013年05月12日 16:14
Also, since we currently don't forbid the following:
>>> {'a': 1, 'a': 2}
{'a': 2}
I don't see why enums should be any different. Recommend closing.
msg189071 - (view) Author: Alyssa Coghlan (ncoghlan) * (Python committer) Date: 2013年05月12日 23:21
The difference is the use case: dicts are a general purpose data store,
enums are typically for defining mutually exclusive named values, with
aliasing as a concession to practical reality.
msg189074 - (view) Author: Guido van Rossum (gvanrossum) * (Python committer) Date: 2013年05月12日 23:41
I'm with Antoine. Trying to prevent accidental redefinition behavior like
Nick proposes feels like un-Pythonic coddling to me, and I expect we'd be
closing off some occasionally useful patterns. Please leave well enough
alone.
msg189083 - (view) Author: Alyssa Coghlan (ncoghlan) * (Python committer) Date: 2013年05月13日 00:06
OK, I mainly wanted to make sure this alternative was at least considered, as I didn't see it come up during the PEP discussions.
msg189138 - (view) Author: Barry A. Warsaw (barry) * (Python committer) Date: 2013年05月13日 14:26
On May 12, 2013, at 06:51 AM, Nick Coghlan wrote:
>>>> class Shape(Enum):
>... square = 2
>... diamond = 1
>... circle = 3
>... alias_for_square = square
I see Guido pronounced against it, but I'm just registering that I kind of
like this. You could probably have guess that since flufl.enum doesn't allow
aliases at all mostly because of the potential for accidental duplicate
values, which this would avoid.
Hmm. LP: #1179529
msg189197 - (view) Author: Alyssa Coghlan (ncoghlan) * (Python committer) Date: 2013年05月14日 03:56
I just wanted to note that there's a trivial way to prevent accidental aliases inline or in your test suite if you don't intend them:
 class MyEnum(Enum):
 ....
 assert len(MyEnum) == len(MyEnum.__members__)
History
Date User Action Args
2022年04月11日 14:57:45adminsetgithub: 62159
2013年05月14日 03:56:24ncoghlansetmessages: + msg189197
2013年05月13日 14:26:48barrysetmessages: + msg189138
2013年05月13日 14:21:44barrysetnosy: + barry
2013年05月13日 00:06:17ncoghlansetstatus: open -> closed
messages: + msg189083

dependencies: - Code, test, and doc review for PEP-0435 Enum
resolution: rejected
stage: needs patch -> resolved
2013年05月12日 23:41:46gvanrossumsetmessages: + msg189074
2013年05月12日 23:21:49ncoghlansetmessages: + msg189071
2013年05月12日 16:14:01pitrousetmessages: + msg189043
2013年05月12日 16:12:42pitrousetnosy: + pitrou
messages: + msg189042
2013年05月12日 16:07:01dilettantsetnosy: + dilettant
2013年05月12日 15:07:24gvanrossumsetnosy: + gvanrossum
2013年05月12日 12:44:41ncoghlansetmessages: + msg189024
2013年05月12日 10:44:26ethan.furmansetnosy: + ethan.furman
messages: + msg189008
2013年05月12日 10:31:49eric.smithsetnosy: + eric.smith
2013年05月12日 10:11:30ncoghlansetpriority: normal -> high
2013年05月12日 07:56:05ncoghlansetmessages: + msg188988
2013年05月12日 06:54:08alexsetnosy: + alex
messages: + msg188983
2013年05月12日 06:51:58ncoghlansetdependencies: + Code, test, and doc review for PEP-0435 Enum
2013年05月12日 06:51:37ncoghlancreate

AltStyle によって変換されたページ (->オリジナル) /