[Python-ideas] PEP for enum library type?

Guido van Rossum guido at python.org
Tue Feb 12 20:13:37 CET 2013


On Tue, Feb 12, 2013 at 10:31 AM, Ethan Furman <ethan at stoneleaf.us> wrote:
> On 02/12/2013 10:08 AM, Guido van Rossum wrote:
>>
>> I'm torn. I like the clean look of Tim's:
>>
>> class Flag(Enum):
>>     RED, WHITE, BLUE
>>
>> However, I don't like the magic needed for its implementation -- and
>> anybody who thinks they know Python pretty well and thinks about this
>> syntax for more than two seconds has to wonder how on earth it's done
>> (and the answer is pretty horrible). It is also pretty brittle to
>> depend on the lookup order -- and I suspect it will be prone to
>> masking other bugs (any typo in a name used in class-level code will
>> essentially generate a bogus new enum value).
>
>
> It seems to me the point of an enum is to give names to an order, so why
> would the lookup order be a problem?

Because the language requirement that the expressions in a tuple are
evaluated left-to-right is fairly weak. (There are other, similar
contexts where the order is not l2r.)

>> OTOH I don't like having the string quotes of Antoine's counter-proposal:
>>
>> class Flag(Enum):
>>      fields = ('RED', 'WHITE', 'BLUE')
>>
>> The compromise that I would personally lean towards is more like this:
>>
>> class Flag(Enum):
>>     RED, WHITE, BLUE = <something>
>>
>> Even if the <something> requires you to know how many values you are
>> defining, like range(3). If we have to have a somewhat more verbose
>> syntax that doesn't bother me too much.
>
>
>
> Having just dealt with using a poor-person's Enum (THIS, THAT, THE_OTHER =
> range(3)) and then having to update it a few times (including all the places
> in the code that depended on the length), I can safely say that the range(n)
> construct is a PITA.
>
> If you don't mind verbose, we could always go for something like:
>
> class Color(Enum):
>     start_defs()
>     BLACK
>     RED, GREEN, BLUE
>     CYAN, YELLOW, MAGENTA
>     end_defs()
>
> and if we mandate that the enum names must come first we can even ditch the
> 'start_defs' call.

If that's where you're leaning I would much rather do this:

class Color(Enum):
  BLACK = val()
  RED = val()
  # etc.

EIBTI.

> As far as typos go, I don't think that's a new problem (it certainly isn't
> for me, anyway ;) and my best defense is plenty of tests.

So with Tim's implementation, what happens here:

class Color(Enum):
  RED, GREEN, BLUE
  if sys.platform == 'win32':
    MAGENTA

and you happen to have no "import sys" in your module? The sys lookup
will succeed, create a new enum, and then you will get an error
something like this:

AttributeError: 'Enum' object has no attribute 'platform'

--
--Guido van Rossum (python.org/~guido)



More information about the Python-ideas mailing list