another enum implementation

I realize this isn't going very far, but I would still appreciate feedback. :) The code is here: https://bitbucket.org/stoneleaf/enum It is based on ideas from Michael Foord, Antoine Pitrou, and (eventually) Ted Delaney. Enum only accepts upper-case names as enum candidates; all enum values must be the same: either 'sequence' (0, 1, 2, etc) or 'flag' (1, 2, 4, etc.) or 'unique' (north, south, east, west, etc.); and extending via subclassing is possible. Sample code: class Color(Enum): type = 'sequence' BLACK RED GREEN = 4 BLUE print Color # Color(BLACK:0, RED:1, GREEN:4, BLUE:5) class MoreColor(Color): MAGENTA YELLOW CYAN print MoreColor # MoreColor(BLACK:0, RED:1, GREEN:4, BLUE:5, MAGENTA:6, YELLOW:7, # CYAN:8) class DbfType(Enum): type = 'unique' CLP DB3 VFP --> print(enum.DbfType) # DbfType(DB3:'db3', CLP:'clp', VFP:'vfp') class SomeFlags(Enum): type = 'flag' ON_DISK HAS_MEMO LARGE_CHAR UNICODE --> print(enum.SomeFlags) # SomeFlags(ON_DISK:1, HAS_MEMO:2, LARGE_CHAR:4, UNICODE:8) class Error(Enum): type = 'sequence' THIS THAT The_Other # raises NameError THOSE = 1 # raises InvalidEnum -->enum.Color.RED Color('RED') -->enum.Color.RED == 1 True -->int(enum.Color.RED) 1 -->enum.SomeFlags.ON_DISK SomeFlags('ON_DISK') -->enum.SomeFlags.ON_DISK == 1 True -->int(enum.SomeFlags.ON_DISK) 1 -->enum.SomeFlags.ON_DISK == enum.Color.RED False -->enum.MoreColor.RED == 1 True -->enum.MoreColor.RED == enum.Color.RED True -->enum.Color(1) Color('RED') -->enum.Color('RED') Color('RED') --> for color in enum.Color: ... print(color) ... BLACK RED GREEN BLUE --> for color in enum.Color: ... print(repr(color)) ... Color('BLACK') Color('RED') Color('GREEN') Color('BLUE') I would appreciate any comments on both the API, and the code behind it. Thanks. -- ~Ethan~

I'm not sure why, but I didn't see anyone making a point about documentation. To me, it's important that stdlib's and other libraries' enums are well documented, and I think that the best way of providing and enforcing this is to mimic "property" builtin. class Color(enum.Sequence): "Some general docs about Color enum" BLACK = enum.value(doc='Black Color') or class Color(enum.Flag): "..." BLACK = enum(doc='Black Color') WHITE = enum() Maybe this is uglier than magic of just writing flags' names, but this implementation is much simpler, backwards compatible with python 2, and verbose. The latter point is both good and bad, but we don't write enums that often to make a bit of verbosity unacceptable. Just my two cents. - Yury On 2013-02-13, at 12:04 AM, Ethan Furman <ethan@stoneleaf.us> wrote:

On 02/12/2013 09:24 PM, Yury Selivanov wrote:
You definitely have a good point about documentation, and I'm going to add the functionality that Tim has in his which will allow other attributes on enum values (the difference with his is that mine are actual instances of their class so all values of one class will have the same attributes). However, for small enums, well chosen names should be documentation enough, so doc strings will not be required. Even more importantly, if I'm just trying something out I do not want to be forced to add stuff I don't need. -- ~Ethan~

Two comments. 1. When it is fully generalized, is type is the way to to specify the type of enums? Or there will be helper functions or classes that can specify the type of enum one desires. 2. Personally, I have resorted to using namedtuples for enum like behavior. How would this class benefit me? Any edification would be helpful. On Tue, Feb 12, 2013 at 9:04 PM, Ethan Furman <ethan@stoneleaf.us> wrote:

On Tue, Feb 12, 2013 at 10:18 PM, Senthil Kumaran <senthil@uthcode.com> wrote:
Two comments.
I should say, I responded without looking at the other thread. If the questions are relevant, please proceed, if not I shall find the answer the other thread which seem to have discussed this topic in greater detail.

On 02/12/2013 10:18 PM, Senthil Kumaran wrote:
Creating enums with the class method is so easy I don't see myself spending time on helper functions. I'll have to think some more about using type = 'unique' vs. class Geometry(UniqueEnum) although I feel myself leaning towards the UniqueEnum style.
namedtuples are designed to have many instances with different values in the same slots; the Enum class is a singleton, and its instances are the values. The Enum class' instances are derived from either int or str, so they can be an easy drop-in replacement to API's that currently expect ints or strs. Better repr()'s. :) -- ~Ethan~ P.S. Definitely read the other thread, and no worries.

I'm not sure why, but I didn't see anyone making a point about documentation. To me, it's important that stdlib's and other libraries' enums are well documented, and I think that the best way of providing and enforcing this is to mimic "property" builtin. class Color(enum.Sequence): "Some general docs about Color enum" BLACK = enum.value(doc='Black Color') or class Color(enum.Flag): "..." BLACK = enum(doc='Black Color') WHITE = enum() Maybe this is uglier than magic of just writing flags' names, but this implementation is much simpler, backwards compatible with python 2, and verbose. The latter point is both good and bad, but we don't write enums that often to make a bit of verbosity unacceptable. Just my two cents. - Yury On 2013-02-13, at 12:04 AM, Ethan Furman <ethan@stoneleaf.us> wrote:

On 02/12/2013 09:24 PM, Yury Selivanov wrote:
You definitely have a good point about documentation, and I'm going to add the functionality that Tim has in his which will allow other attributes on enum values (the difference with his is that mine are actual instances of their class so all values of one class will have the same attributes). However, for small enums, well chosen names should be documentation enough, so doc strings will not be required. Even more importantly, if I'm just trying something out I do not want to be forced to add stuff I don't need. -- ~Ethan~

Two comments. 1. When it is fully generalized, is type is the way to to specify the type of enums? Or there will be helper functions or classes that can specify the type of enum one desires. 2. Personally, I have resorted to using namedtuples for enum like behavior. How would this class benefit me? Any edification would be helpful. On Tue, Feb 12, 2013 at 9:04 PM, Ethan Furman <ethan@stoneleaf.us> wrote:

On Tue, Feb 12, 2013 at 10:18 PM, Senthil Kumaran <senthil@uthcode.com> wrote:
Two comments.
I should say, I responded without looking at the other thread. If the questions are relevant, please proceed, if not I shall find the answer the other thread which seem to have discussed this topic in greater detail.

On 02/12/2013 10:18 PM, Senthil Kumaran wrote:
Creating enums with the class method is so easy I don't see myself spending time on helper functions. I'll have to think some more about using type = 'unique' vs. class Geometry(UniqueEnum) although I feel myself leaning towards the UniqueEnum style.
namedtuples are designed to have many instances with different values in the same slots; the Enum class is a singleton, and its instances are the values. The Enum class' instances are derived from either int or str, so they can be an easy drop-in replacement to API's that currently expect ints or strs. Better repr()'s. :) -- ~Ethan~ P.S. Definitely read the other thread, and no worries.
participants (3)
-
Ethan Furman
-
Senthil Kumaran
-
Yury Selivanov