<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Sat, Apr 13, 2013 at 1:31 AM, Serhiy Storchaka <span dir="ltr"><<a href="mailto:storchaka@gmail.com" target="_blank">storchaka@gmail.com</a>></span> wrote:<br>

<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="im">On 12.04.13 15:55, Eli Bendersky wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
The enumeration value names are available through the class members::<br>
<br>
     >>> for member in Colors.__members__:<br>
     ...     print(member)<br>
     red<br>
     green<br>
     blue<br>
</blockquote>
<br></div>
This is unnecessary because enumerations are iterable. Colors.__members__ is equal to [<a href="http://v.name" target="_blank">v.name</a> for v in Colors] and the latter looks more preferable, because it does not use the magic method.<div class="im">

<br></div></blockquote><div><br></div><div>Right. Fixed (removed this part because it's redundant), thanks.<br></div><div><br> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

<div class="im">
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
The str and repr of the enumeration class also provides useful information::<br>
<br>
     >>> print(Colors)<br>
     <Colors {red: 1, green: 2, blue: 3}><br>
     >>> print(repr(Colors))<br>
     <Colors {red: 1, green: 2, blue: 3}><br>
</blockquote>
<br></div>
Does the enumeration's repr() use str() or repr() for the enumeration values? And same question for the enumeration's str().<div class="im"><br></div></blockquote><div><br></div><div>str<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

<div class="im">
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
To programmatically access enumeration values, use ``getattr``::<br>
<br>
     >>> getattr(Colors, 'red')<br>
     <EnumValue: Colors.red [value=1]><br>
</blockquote>
<br></div>
How to get the enumeration value by its value?<div class="im"><br></div></blockquote><div><br></div><div>I've updated the PEP since then. It also shows how to use __getitem__ syntax to access by value.<br></div><div>

 </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="im">
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Ordered comparisons between enumeration values are *not* supported.  Enums<br>
are<br>
not integers (but see `IntEnum`_ below)::<br>
</blockquote>
<br></div>
It's unexpected if values of the enumeration values have the natural order. And values of the enumeration values *should be* comparable ("Iteration is defined as the sorted order of the item values").<br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Enumeration values<br>
------------------<br>
</blockquote>
<br>
There is some ambiguity in the term "enumeration values". On the one hand, it's the singleton instances of the enumeration class (Colors.red, Colors.gree, Colors.blue), and on the other hand it is their values (1, 2, 3).<div class="im">

<br></div></blockquote><div><br></div><div>I agree, but not sure how to resolve it. I hope it's clear enough from the context.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

<div class="im">
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
But if the value *is* important,  enumerations can have arbitrary values.<br>
</blockquote>
<br></div>
Should enumeration values be hashable?<br>
<br></blockquote><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
At least they should be comparable ("Iteration is defined as the sorted order of the item values").<div class="im"><br></div></blockquote><div><br></div><div>See long discussion previously in this thread.<br></div>

<div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="im">
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
``IntEnum`` values behave like integers in other ways you'd expect::<br>
<br>
     >>> int(Shape.circle)<br>
     1<br>
     >>> ['a', 'b', 'c'][Shape.circle]<br>
     'b'<br>
     >>> [i for i in range(Shape.square)]<br>
     [0, 1]<br>
</blockquote>
<br></div>
What is ``isinstance(Shape.circle, int)``? Does PyLong_Check() return true for ``IntEnum`` values?<div class="im"><br></div></blockquote><div><br></div><div>Yes. IntEnumValue (the value class underlying IntEnum) subclasses int.<br>

</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="im">
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Enumerations created with the class syntax can also be pickled and<br>
unpickled::<br>
</blockquote>
<br></div>
This does not apply to marshalling, I suppose? Perhaps this is worth to mention explicitly. There may be some errors of incompatibility.</blockquote><div><br></div><div>No special provision has been made for marshalling.<br>

</div><div class="im"> <br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
The ``Enum`` class is callable, providing the following convenience API::<br>
<br>
     >>> Animals = Enum('Animals', 'ant bee cat dog')<br>
     >>> Animals<br>
     <Animals {ant: 1, bee: 2, cat: 3, dog: 4}><br>
     >>> Animals.ant<br>
     <EnumValue: Animals.ant [value=1]><br>
     >>> Animals.ant.value<br>
     1<br>
<br>
The semantics of this API resemble ``namedtuple``. The first argument of<br>
the call to ``Enum`` is the name of the enumeration.  The second argument is<br>
a source of enumeration value names.  It can be a whitespace-separated<br>
string<br>
of names, a sequence of names or a sequence of 2-tuples with key/value<br>
pairs.<br>
</blockquote>
<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Why the enumeration starts from 1? It is not consistent with namedtuple, in which indices are zero-based, and I believe that in most practical cases the enumeration integer values are zero-based.</blockquote><br>I don't know if there was a special reason for this. Perhaps backwards compatibility with existing flufl.enum APIs. Barry may know more about this.<br>

<div class="im"> <br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Use-cases in the standard library<br>
=================================<br>
</blockquote>
<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
The Python standard library has many places where named integer constants used as bitmasks (i.e. os.O_CREAT | os.O_WRONLY | os.O_TRUNC, select.POLLIN | select.POLLPRI, re.IGNORECASE | re.ASCII). The proposed PEP is not applicable to these cases. Whether it is planned expansion of Enum or additional EnumSet class to aid in these cases?</blockquote>

<div> <br></div></div>It is applicable, in the sense that os.O_CREAT etc can be IntEnum values. Their bitset operation results will be simple integers. It's not planned to add a special enum for this - this was ruled against during the Pycon discussions.<br>

<br>Eli<br><br></div><div class="gmail_extra"><br><br></div></div>