[Python-ideas] PEP for enum library type?

Ethan Furman ethan at stoneleaf.us
Fri Feb 22 19:46:27 CET 2013


On 02/22/2013 09:07 AM, Andrew Barnert wrote:
> On Feb 21, 2013, at 15:24, Greg Ewing <greg.ewing at canterbury.ac.nz> wrote:
>
>> On 22/02/13 08:18, Alex Stewart wrote:
>>>
>>> It doesn't seem
>>> unreasonable, therefore, to define two different categories of enums: one that
>>> has no concept of "value" (for pure-Python), and one which does have
>>> associated values but all values have to be specified explicitly
>>
>> That sounds reasonable. However, I'm wondering if there isn't a
>> third case: where you don't care about the values, but you do
>> want them to have a defined ordering?
>
> And a fourth case: You don't care about the values, but you want to be able to | them together into a set.
>
> For example, consider file open flags, mmap access flags, chmod flags, etc. You need some way to pass READ | TEXT, WRITE | SHARED, etc. occasionally, but most of the time you just pass READ or WRITE. It wouldn't be too onerous to require an explicit {READ, SHARED} set for the uncommon case, but set(READ) for the common case would be horrible. And you don't want every function that takes enums to typeswitch so it can handle a single value as if it were a set. The obvious answer to this is the one every other language uses: take READ | SHARED.
>
> This doesn't have to mean flag enums have integral values. However, the only alternative I can think of is that enums have set syntax, so READ | SHARED returns something like READ.__class__({READ, SHARED}), which of course also means that set has to automatically be a valid value for the type. Which is pretty magical and complex.
>
> Of course the answer could be not to allow that. Call mmap(file, access=WRITE, contention=SHARED), not mmap(WRITE | SHARED). But if we're talking about changing the stdlib and hopefully most popular third party libs, that would be a pretty drastic change.
>
> Finally, the answer could be: if you want that, you have to give them int values, and accept ints instead of enums in your APIs, at which point I think the benefit of valueless enums has gone way down, because many places you'd think you want them (including all over the stdlib), you don't.

We shouldn't get hung up on "don't care about the values" == "no value assigned".  I personally don't see any value in a 
valueless enum; I do see value in three other types: sequence (based on int), bitmask (based on int), and unique (or 
string -- based on str).  It seems to me that we're throwing around "valueless" because we don't want some enums to 
support math operations -- so use the string version for that type.

As for your example above:

Python 3.2.3 (default, Oct 19 2012, 19:53:16)
[GCC 4.7.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.

-->from yaenum import BitMaskEnum, enum

-->BitMaskEnum.create('MMap', 'READ WRITE TEXT SHARED', export=globals())
<class 'yaenum.MMap'>

-->READ, WRITE, TEXT, SHARED
(MMap('READ', value=1), MMap('WRITE', value=2), MMap('TEXT', value=4), MMap('SHARED', value=8))

-->READ | TEXT
MMap('READ|TEXT', value=5)

-->WRITE | SHARED
MMap('WRITE|SHARED', value=10)



More information about the Python-ideas mailing list