[Python-Dev] [Python-checkins] peps: Pre-alpha draft for PEP 435 (enum). The name is not important at the moment, as (original) (raw)

Eric Snow ericsnowcurrently at gmail.com
Thu Feb 28 10:56:07 CET 2013


Having had some time to think about this problem space, here's my take on it:

===============================

The problem-space can be broken down into four layers:

  1. the items
  2. interaction between grouped items
  3. the grouping itself
  4. conversion from a class to a group

Here are potential characteristics at each layer:

items

items and item interaction

groups

conversion

There is a danger in trying to make an "enum" that is capable of doing everything. People need a simple common ground. When an object is an enum, a developer should be able to know immediately how to interact with it and that interaction should have a small cross-section.

===============================

With that in mind and considering a lot of the discussion that has gone on, here's an API that tries to find a middle ground:

"items"

NamedValue #Nick's recipe NamedItem #an opaque named wrapper around a value group # the "enum" to which the item belongs value # the wrapped value qualname # group qualname + item name repr -> class + qualname + value str -> item name eq -> NotImplemented expose(ns) # export the value out to any namespace OrderedItem(NamedItem) # a totally ordered item eq -> other is self lt -> ask self.group to decide FlagItem(NamedItem) # a bitwise/set operation compatible item and -> ask self.group to do it ... FlagsItem(FlagItem) # the result of FlagItem bitwise operations repr -> shows the the items or'ed together items # the items that were joined together by the operation IntItem(NamedItem) # for those that really need a named item to be a little less opaque int index bool

" groups"

Group name qualname items # the underlying collection of items (tuple or frozenset) _ns # a GroupValues instance for the group repr -> group name + items call(value) -> item # essentially the unserializer for an item _expose(ns) # calls expose() on each item in the group OrderedGroup # corresponds to OrderedItem FlagGroup # corresponds to FlagItem GroupValues # a Mapping proxy around a group's (name -> value)

"conversion"

named_values_from_class() -> {name: value} # simply extract the values from the class auto_int_from_class() # a classic enum auto_bin_from_class() # similar but steps in powers of 2 as_enum(*, ordered=False, flagged=False, converter=..., strict=True, **kwargs) # the main class decorator factory

Examples:

@as_enum() class Spam: A = ... B = ... C = ...

Spam.A._expose(globals())

@as_enum(converter=auto_bin_from_class, flagged=True) class Ham: A = 1 B = ... C = ... D = 32

Ham.A == 1 # False Ham.B | Ham.C # a FlagsItem containing the two iter(Ham) # TypeError iter(Ham.items) # the items iter(Ham._ns) # the names iter(Ham._ns.values()) # the values

Key points:

In the interest of having something more concrete, a very raw and still relatively non-functional implementation of the above API can be found at:

https://bitbucket.org/ericsnowcurrently/odds_and_ends/src/default/enum.py

Finally, like I said before, the smaller the API the better. Obviously what I've got here could be distilled. However, it does capture the way I see the separate layers here.

-eric



More information about the Python-Dev mailing list