Path: csiph.com!usenet.pasdenom.info!weretis.net!feeder4.news.weretis.net!newsreader4.netcologne.de!news.netcologne.de!xlned.com!feeder3.xlned.com!news2.euro.net!newsgate.cistron.nl!newsgate.news.xs4all.nl!post.news.xs4all.nl!not-for-mail Return-Path: X-Original-To: python-list@python.org Delivered-To: python-list@mail.python.org X-Spam-Status: OK 0.000 X-Spam-Evidence: '*H*': 1.00; '*S*': 0.00; '(at': 0.03; 'subject:Python': 0.05; 'binary': 0.05; 'modified': 0.05; 'sys': 0.05; 'url:bitbucket': 0.05; '%s"': 0.07; 'assign': 0.07; 'seemed': 0.07; 'subject:ANN': 0.07; '(although': 0.09; 'blue': 0.09; 'enum': 0.09; 'from:addr:ethan': 0.09; 'from:addr:stoneleaf.us': 0.09; 'from:name:ethan furman': 0.09; 'globals': 0.09; 'lookup': 0.09; 'message-id:@stoneleaf.us': 0.09; 'received:184.172': 0.09; 'received:gator410.hostgator.com': 0.09; 'subclass': 0.09; 'def': 0.10; 'thread': 0.11; 'finished': 0.15; '"%s': 0.16; 'desc': 0.16; 'discarded': 0.16; 'failed.': 0.16; 'increment': 0.16; 'metaclass': 0.16; 'stdlib.': 0.16; 'prototype': 0.17; 'skip:p 30': 0.20; 'putting': 0.20; 'import': 0.21; 'fairly': 0.21; 'seems': 0.23; 'idea': 0.24; 'least': 0.25; 'header:User-Agent:1': 0.26; 'values': 0.26; 'skip:# 10': 0.27; 'closer': 0.29; 'probably': 0.29; 'class': 0.29; "skip:' 10": 0.30; 'code': 0.31; 'to:addr:python-list': 0.33; 'another': 0.33; "won't": 0.35; 'there': 0.35; 'url:org': 0.36; 'skip:p 20': 0.36; 'subject:: ': 0.38; 'green': 0.38; 'some': 0.38; 'to:addr:python.org': 0.39; 'header:Received:5': 0.40; 'bottom': 0.60; 'red': 0.60; 'here:': 0.62; 'here': 0.65; 'received:67.18': 0.65; 'status:': 0.65; 'code):': 0.84; 'enumeration': 0.84; 'greetings!': 0.84; 'to:name:python': 0.84; 'together,': 0.84; 'yellow': 0.84; 'received:gateway14.websitewelcome.com': 0.91 Date: Sat, 16 Feb 2013 12:33:41 -0800 From: Ethan Furman User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:17.0) Gecko/20130106 Thunderbird/17.0.2 MIME-Version: 1.0 To: Python Subject: ANN: Python 3 enum package Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit X-AntiAbuse: This header was added to track abuse, please include it with any abuse report X-AntiAbuse: Primary Hostname - gator410.hostgator.com X-AntiAbuse: Original Domain - python.org X-AntiAbuse: Originator/Caller UID/GID - [47 12] / [47 12] X-AntiAbuse: Sender Address Domain - stoneleaf.us X-BWhitelist: yes X-Source: X-Source-Args: X-Source-Dir: X-Source-Sender: ([173.12.184.235]) [173.12.184.235]:47629 X-Source-Auth: ethan+stoneleaf.us X-Email-Count: 1 X-Source-Cap: dG9idWs7dG9idWs7Z2F0b3I0MTAuaG9zdGdhdG9yLmNvbQ== X-BeenThere: python-list@python.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: General discussion list for the Python programming language List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Newsgroups: comp.lang.python Message-ID: Lines: 135 NNTP-Posting-Host: 2001:888:2000:d::a6 X-Trace: 1361047892 news.xs4all.nl 6941 [2001:888:2000:d::a6]:37461 X-Complaints-To: abuse@xs4all.nl Xref: csiph.com comp.lang.python:39010 Greetings! There was a recent thread on Python-Ideas about adding an enumeration package to the stdlib. One idea that seemed to be fairly popular (at least I like it a lot ;) was the use of a metaclass to automatically assign values when a name lookup failed. It was also fairly unpopular and so probably won't make it in (although another good one seems poised to be accepted -- flufl.enum, I believe). At any rate, I finished putting my prototype together, and it is available on github here: https://bitbucket.org/stoneleaf/enum And here is some sample code so you can see if you would like to take a closer look (comments and critiques welcome): 8<---------------------------------------------------------------------------------- #!/usr/bin/python3 from enum import Enum, BitMaskEnum, UniqueEnum, enum class Color(Enum): "basic red/green/blue" black red green blue print(Color) print(Color.green) print(Color(2)) print(Color('green')) print(repr(Color.green)) class MoreColor(Color): "and some cyan/magenta/yellow" cyan magenta yellow print(MoreColor) print(MoreColor.red) print(MoreColor(1)) print(MoreColor('red')) print(repr(MoreColor.red)) class Errors(Enum): missing closed corrupted modified print(Errors) print(Errors.closed) print(Errors(1)) print(Errors('closed')) print(repr(Errors.closed)) print(Color.red in Color) print(MoreColor.magenta in MoreColor) print(Color.red in MoreColor) print(Color.red == MoreColor.red) print(not (Errors.closed in MoreColor)) print(not (Errors.closed in Color)) print(not (Errors.closed == Color.red)) print(not (Errors.closed == MoreColor.red)) class Status(BitMaskEnum): has_memo binary increment unicoded print(Status) for e in Status: print(repr(e)) print(Status.binary | Status.increment) print(Status(5)) print(Status('binary|increment')) print(repr(Status(5))) class Position(UniqueEnum): LEFT RIGHT TOP BOTTOM print(Position) print(Position.TOP) print(Position('top')) print(Position('TOP')) print(repr(Position.TOP)) #return class discarded print(Enum.create('IceCream', 'chocolate vanilla strawberry')) #class stuffed into globals Enum.create('IceCream', 'chocolate vanilla strawberry', namespace=globals()) print(IceCream) # can even subclass this way import sys Enum.create( 'MoreIceCream', 'cherry rockyroad coconut', bases=(IceCream,), namespace=sys.modules) from MoreIceCream import * # and import from it print(cherry) print() # and if you don't like the magic, don't use it :) class Color(BitMaskEnum): black = enum('midnight', '#000', value=0) red = enum('sunset', '#001') green = enum('emerald', '#010') blue = enum('sky', '#100') def __init__(yo, desc, code): "value is automatically saved" yo.desc = desc yo.code = code def describe(yo, noun): return "%s %s" % (yo.desc, noun) print(Color) print(Color.green) print(repr(Color.green)) print(Color.green.describe('glow')) 8<----------------------------------------------------------------------------------