On Feb 21, 2013, at 15:24, Greg Ewing greg.ewing@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.