File: enum.py

package info (click to toggle)
libaqbanking 2.2.3-3
  • links: PTS
  • area: main
  • in suites: etch, etch-m68k
  • size: 14,912 kB
  • ctags: 6,430
  • sloc: ansic: 59,251; cpp: 17,347; sh: 8,930; xml: 6,189; makefile: 3,326; python: 2,806; pascal: 559; perl: 267
file content (94 lines) | stat: -rw-r--r-- 2,637 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
# -*- encoding: latin1 -*-
# based on examples/Demo/newmetaclasses/Enum.py of the
# python distribution V2.3.
#
# Copyright for changes:
# Copyright (C) 2005 by Andreas Degert
# see LICENSE.txt in the top level distribution directory
#
"""Enumeration metaclass."""

class EnumMetaclass(type):
    "Metaclass for enumeration."

    def __init__(cls, name, bases, dict):
        cls._members = []
        cls._memberdict = {}
        for attr, value in dict.items():
            if not (attr.startswith('__') and attr.endswith('__')):
                EnumInstance(cls, attr, value)

    def __call__(cls, value):
        try:
            return cls._memberdict[value]
        except KeyError:
            raise ValueError("%s not found in enum %s" % (value, cls.__name__))

    def __repr__(cls):
        if cls._members:
            l = [(getattr(cls, val), val) for val in cls._members]
            l.sort()
            s = ': {%s}' % ', '.join(["%s: %d" % (val, attr)
                                      for attr, val in l])
        else:
            s = ''
        return "%s%s" % (cls.__name__, s)

class EnumInstance(int):
    "Class to represent an enumeration value."

    def __new__(cls, classobj, enumname, value):
        return int.__new__(cls, value)

    def __init__(self, classobj, enumname, value):
        try:
            n = classobj._memberdict[value]
            raise ValueError(
                'Value %d found twice in Enum %s: %s, %s'
                % (value, classobj.__name__, n.__enumname, enumname))
        except KeyError:
            pass
        classobj._memberdict[value] = self
        classobj._members.append(enumname)
        setattr(classobj, enumname, self)
        self.enumclass = classobj
        self.__enumname = enumname

    def __repr__(self):
        return "EnumInstance(%s, %s, %d)" % (
            self.enumclass.__name__, self.__enumname, self)

    def __str__(self):
        return "%s.%s" % (self.enumclass.__name__, self.__enumname)

class Enum:
    """Class to use as a base class for an enumeration.

    class TestEnum(Enum):
        a = 1
        b = 2
    """
    __metaclass__ = EnumMetaclass


def check_enum(value, cls, name):
    if not isinstance(value, EnumInstance) or value.enumclass is not cls:
        raise TypeError("%s must be a %s" % (name, cls.__name__))

if __name__ == '__main__':
    class T(Enum):
        a, b = range(1,3)

    print T
    print T.a
    print T(T.a+1)
    try:
        print T(3)
    except ValueError, e:
        print e
    try:
        class B(Enum):
            a = b = 2
        print B
    except ValueError, e:
        print e