[Python-Dev] backported Enum

Barry Warsaw barry at python.org
Wed Jun 19 05:04:03 CEST 2013


On Jun 16, 2013, at 01:13 PM, Eli Bendersky wrote:

>If you write down the process of porting mailmain from flufl to stdlib.enum
>in some place, it can make the process much easier for others, and even
>encourage them to follow the same path.

Let's write it down here!  It was mostly mechanical, and some probably would
have been done to fix deprecations in flufl.enum.  Here's the list.

Switching from call syntax to getitem syntax for looking up an enum member by
name, e.g.

    -        delivery_mode = DeliveryMode(data['delivery_mode'])
    +        delivery_mode = DeliveryMode[data['delivery_mode']]

Switching from getitem syntax to call syntax for looking up an enum member by
value, e.g.

    -        return self._enum[value]
    +        return self._enum(value)

Interesting that these two were exactly opposite from flufl.enum.

Switching from int() to .value to get the integer value of an enum member,
e.g.

    -    return (member.list_id, member.address.email, int(member.role))
    +    return (member.list_id, member.address.email, member.role.value)

Changing the imports (obviously), e.g.

    -from flufl.enum import Enum
    +from enum import Enum

Adapting to the different repr as seen in a doctest, e.g.

    -    <EnumValue: Response.hold [int=1]>
    +    <Response.hold: 1>

Fixing some type tests.  I have one case that was testing for an enum member
to do value type conversion.  Since enum members are now instances of their
enum class, and because members no longer have a .enum attribute (because you
can just ask for its __class__), the type test actually became simpler:

    -        elif hasattr(obj, 'enum') and issubclass(obj.enum, Enum):
    +        elif isinstance(obj, Enum):

An unexpected difference is that failing name lookups raise a KeyError instead
of a ValueError.  There are many cases where I catch failing lookups in my
REST API.  Fixing this was mostly easy...

    -    except ValueError:
    +    except KeyError:

...except in one case where I was previously allowing the ValueError to
percolate up to signal to a higher level that some exception handling had to
be done.  Here, I had to convert the exception:

    -        # This will raise a ValueError if the enum value is unknown.  Let
    -        # that percolate up.
    -        return self._enum_class[enum_value]
    +        # This will raise a KeyError if the enum value is unknown.  The
    +        # Validator API requires turning this into a ValueError.
    +        try:
    +            return self._enum_class[enum_value]
    +        except KeyError as exception:
    +            # Retain the error message.
    +            raise ValueError(exception.message)

Interestingly, I found an existing hidden bug in an upgrade script where I was
not converting a value from an integer to an enum.  Nice to catch that one.

For now, I'll hold out on merging this branch to trunk until I can get enum34
packaged up for Debian.  Other than that, it looks pretty good!

Merge proposal: http://tinyurl.com/l2fq38l
Branch: https://code.launchpad.net/~barry/mailman/pep435

-Barry
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: not available
URL: <http://mail.python.org/pipermail/python-dev/attachments/20130618/bec98f6f/attachment-0001.pgp>


More information about the Python-Dev mailing list