[Python-Dev] PEP 435 -- Adding an Enum type to the Python standard library
R. David Murray
rdmurray at bitdance.com
Fri Apr 12 15:58:48 CEST 2013
On Fri, 12 Apr 2013 05:55:00 -0700, Eli Bendersky <eliben at gmail.com> wrote:
> Link to the PEP: http://www.python.org/dev/peps/pep-0435/ [it's also pasted
> fully below for convenience].
This looks great. There's just one bit I don't understand. I'm sure
it was discussed in the python-ideas thread, but the discussion of it
in the PEP does not provide any motivation for the decision.
> The ``Enum`` class supports iteration. Iteration is defined as the
> sorted order of the item values::
>
> >>> class FiveColors(Enum):
> ... pink = 4
> ... cyan = 5
> ... green = 2
> ... blue = 3
> ... red = 1
> >>> [v.name for v in FiveColors]
> ['red', 'green', 'blue', 'pink', 'cyan']
[...]
> Ordered comparisons between enumeration values are *not* supported. Enums
> are
> not integers (but see `IntEnum`_ below)::
>
> >>> Colors.red < Colors.blue
> Traceback (most recent call last):
> ...
> NotImplementedError
> >>> Colors.red <= Colors.blue
> Traceback (most recent call last):
> ...
> NotImplementedError
> >>> Colors.blue > Colors.green
> Traceback (most recent call last):
> ...
> NotImplementedError
> >>> Colors.blue >= Colors.green
> Traceback (most recent call last):
> ...
> NotImplementedError
This is the part that I don't understand. Enums *clearly* have an
ordering, since the iteration order is defined and stable. Why should
I not be allowed to compare values from the same Enum type? There are
certainly use cases where that is very useful.
To give you a concrete use case: consider response codes from a client
server application constructed the way typical internet protocols are.
We might have:
class MyAppCode(Enum):
ok = 200
command_complete = 201
status_response = 202
help_response = 203
service_ready = 204
signoff_accepted = 205
temporary_failure = 400
service_not_available = 401
server_error = 402
out_of_resources = 403
error = 500
syntax_error = 501
command_not_implemented = 502
access_denied = 503
resource_not_found = 504
It can be quite handy to be able to say things like:
code = myapp.operation(opstring)
if MyAppCode.temporary_failure < code < MyAppCode.error:
myframework.requeue(opstring, code=code)
return False
elif code > MyAppCode.error:
raise AppError(code)
....
In talking to an existing internet protocol it would be natural to use
IntEnum and this issue would not arise, but I have recently worked on
an application that had *exactly* the above sort of enumeration used
internally, when it would have been totally appropriate to use Enum rather
than IntEnum. The ap has several places where an ordered comparison
against the enum is used to check if a code is in the error range or not.
--David
More information about the Python-Dev
mailing list