1``enum`` --- support for enumerations 2======================================== 3 4.. :synopsis: enumerations are sets of symbolic names bound to unique, constant 5 values. 6.. :moduleauthor:: Ethan Furman <ethan@stoneleaf.us> 7.. :sectionauthor:: Barry Warsaw <barry@python.org>, 8.. :sectionauthor:: Eli Bendersky <eliben@gmail.com>, 9.. :sectionauthor:: Ethan Furman <ethan@stoneleaf.us> 10 11---------------- 12 13An enumeration is a set of symbolic names (members) bound to unique, constant 14values. Within an enumeration, the members can be compared by identity, and 15the enumeration itself can be iterated over. 16 17 18Module Contents 19--------------- 20 21This module defines two enumeration classes that can be used to define unique 22sets of names and values: ``Enum`` and ``IntEnum``. It also defines 23one decorator, ``unique``. 24 25``Enum`` 26 27Base class for creating enumerated constants. See section `Functional API`_ 28for an alternate construction syntax. 29 30``IntEnum`` 31 32Base class for creating enumerated constants that are also subclasses of ``int``. 33 34``unique`` 35 36Enum class decorator that ensures only one name is bound to any one value. 37 38 39Creating an Enum 40---------------- 41 42Enumerations are created using the ``class`` syntax, which makes them 43easy to read and write. An alternative creation method is described in 44`Functional API`_. To define an enumeration, subclass ``Enum`` as 45follows:: 46 47 >>> from enum import Enum 48 >>> class Color(Enum): 49 ... red = 1 50 ... green = 2 51 ... blue = 3 52 53Note: Nomenclature 54 55 - The class ``Color`` is an *enumeration* (or *enum*) 56 - The attributes ``Color.red``, ``Color.green``, etc., are 57 *enumeration members* (or *enum members*). 58 - The enum members have *names* and *values* (the name of 59 ``Color.red`` is ``red``, the value of ``Color.blue`` is 60 ``3``, etc.) 61 62Note: 63 64 Even though we use the ``class`` syntax to create Enums, Enums 65 are not normal Python classes. See `How are Enums different?`_ for 66 more details. 67 68Enumeration members have human readable string representations:: 69 70 >>> print(Color.red) 71 Color.red 72 73...while their ``repr`` has more information:: 74 75 >>> print(repr(Color.red)) 76 <Color.red: 1> 77 78The *type* of an enumeration member is the enumeration it belongs to:: 79 80 >>> type(Color.red) 81 <enum 'Color'> 82 >>> isinstance(Color.green, Color) 83 True 84 >>> 85 86Enum members also have a property that contains just their item name:: 87 88 >>> print(Color.red.name) 89 red 90 91Enumerations support iteration. In Python 3.x definition order is used; in 92Python 2.x the definition order is not available, but class attribute 93``__order__`` is supported; otherwise, value order is used:: 94 95 >>> class Shake(Enum): 96 ... __order__ = 'vanilla chocolate cookies mint' # only needed in 2.x 97 ... vanilla = 7 98 ... chocolate = 4 99 ... cookies = 9 100 ... mint = 3 101 ... 102 >>> for shake in Shake: 103 ... print(shake) 104 ... 105 Shake.vanilla 106 Shake.chocolate 107 Shake.cookies 108 Shake.mint 109 110The ``__order__`` attribute is always removed, and in 3.x it is also ignored 111(order is definition order); however, in the stdlib version it will be ignored 112but not removed. 113 114Enumeration members are hashable, so they can be used in dictionaries and sets:: 115 116 >>> apples = {} 117 >>> apples[Color.red] = 'red delicious' 118 >>> apples[Color.green] = 'granny smith' 119 >>> apples == {Color.red: 'red delicious', Color.green: 'granny smith'} 120 True 121 122 123Programmatic access to enumeration members and their attributes 124--------------------------------------------------------------- 125 126Sometimes it's useful to access members in enumerations programmatically (i.e. 127situations where ``Color.red`` won't do because the exact color is not known 128at program-writing time). ``Enum`` allows such access:: 129 130 >>> Color(1) 131 <Color.red: 1> 132 >>> Color(3) 133 <Color.blue: 3> 134 135If you want to access enum members by *name*, use item access:: 136 137 >>> Color['red'] 138 <Color.red: 1> 139 >>> Color['green'] 140 <Color.green: 2> 141 142If have an enum member and need its ``name`` or ``value``:: 143 144 >>> member = Color.red 145 >>> member.name 146 'red' 147 >>> member.value 148 1 149 150 151Duplicating enum members and values 152----------------------------------- 153 154Having two enum members (or any other attribute) with the same name is invalid; 155in Python 3.x this would raise an error, but in Python 2.x the second member 156simply overwrites the first:: 157 158 >>> # python 2.x 159 >>> class Shape(Enum): 160 ... square = 2 161 ... square = 3 162 ... 163 >>> Shape.square 164 <Shape.square: 3> 165 166 >>> # python 3.x 167 >>> class Shape(Enum): 168 ... square = 2 169 ... square = 3 170 Traceback (most recent call last): 171 ... 172 TypeError: Attempted to reuse key: 'square' 173 174However, two enum members are allowed to have the same value. Given two members 175A and B with the same value (and A defined first), B is an alias to A. By-value 176lookup of the value of A and B will return A. By-name lookup of B will also 177return A:: 178 179 >>> class Shape(Enum): 180 ... __order__ = 'square diamond circle alias_for_square' # only needed in 2.x 181 ... square = 2 182 ... diamond = 1 183 ... circle = 3 184 ... alias_for_square = 2 185 ... 186 >>> Shape.square 187 <Shape.square: 2> 188 >>> Shape.alias_for_square 189 <Shape.square: 2> 190 >>> Shape(2) 191 <Shape.square: 2> 192 193 194Allowing aliases is not always desirable. ``unique`` can be used to ensure 195that none exist in a particular enumeration:: 196 197 >>> from enum import unique 198 >>> @unique 199 ... class Mistake(Enum): 200 ... __order__ = 'one two three four' # only needed in 2.x 201 ... one = 1 202 ... two = 2 203 ... three = 3 204 ... four = 3 205 Traceback (most recent call last): 206 ... 207 ValueError: duplicate names found in <enum 'Mistake'>: four -> three 208 209Iterating over the members of an enum does not provide the aliases:: 210 211 >>> list(Shape) 212 [<Shape.square: 2>, <Shape.diamond: 1>, <Shape.circle: 3>] 213 214The special attribute ``__members__`` is a dictionary mapping names to members. 215It includes all names defined in the enumeration, including the aliases:: 216 217 >>> for name, member in sorted(Shape.__members__.items()): 218 ... name, member 219 ... 220 ('alias_for_square', <Shape.square: 2>) 221 ('circle', <Shape.circle: 3>) 222 ('diamond', <Shape.diamond: 1>) 223 ('square', <Shape.square: 2>) 224 225The ``__members__`` attribute can be used for detailed programmatic access to 226the enumeration members. For example, finding all the aliases:: 227 228 >>> [name for name, member in Shape.__members__.items() if member.name != name] 229 ['alias_for_square'] 230 231Comparisons 232----------- 233 234Enumeration members are compared by identity:: 235 236 >>> Color.red is Color.red 237 True 238 >>> Color.red is Color.blue 239 False 240 >>> Color.red is not Color.blue 241 True 242 243Ordered comparisons between enumeration values are *not* supported. Enum 244members are not integers (but see `IntEnum`_ below):: 245 246 >>> Color.red < Color.blue 247 Traceback (most recent call last): 248 File "<stdin>", line 1, in <module> 249 TypeError: unorderable types: Color() < Color() 250 251.. warning:: 252 253 In Python 2 *everything* is ordered, even though the ordering may not 254 make sense. If you want your enumerations to have a sensible ordering 255 check out the `OrderedEnum`_ recipe below. 256 257 258Equality comparisons are defined though:: 259 260 >>> Color.blue == Color.red 261 False 262 >>> Color.blue != Color.red 263 True 264 >>> Color.blue == Color.blue 265 True 266 267Comparisons against non-enumeration values will always compare not equal 268(again, ``IntEnum`` was explicitly designed to behave differently, see 269below):: 270 271 >>> Color.blue == 2 272 False 273 274 275Allowed members and attributes of enumerations 276---------------------------------------------- 277 278The examples above use integers for enumeration values. Using integers is 279short and handy (and provided by default by the `Functional API`_), but not 280strictly enforced. In the vast majority of use-cases, one doesn't care what 281the actual value of an enumeration is. But if the value *is* important, 282enumerations can have arbitrary values. 283 284Enumerations are Python classes, and can have methods and special methods as 285usual. If we have this enumeration:: 286 287 >>> class Mood(Enum): 288 ... funky = 1 289 ... happy = 3 290 ... 291 ... def describe(self): 292 ... # self is the member here 293 ... return self.name, self.value 294 ... 295 ... def __str__(self): 296 ... return 'my custom str! {0}'.format(self.value) 297 ... 298 ... @classmethod 299 ... def favorite_mood(cls): 300 ... # cls here is the enumeration 301 ... return cls.happy 302 303Then:: 304 305 >>> Mood.favorite_mood() 306 <Mood.happy: 3> 307 >>> Mood.happy.describe() 308 ('happy', 3) 309 >>> str(Mood.funky) 310 'my custom str! 1' 311 312The rules for what is allowed are as follows: _sunder_ names (starting and 313ending with a single underscore) are reserved by enum and cannot be used; 314all other attributes defined within an enumeration will become members of this 315enumeration, with the exception of *__dunder__* names and descriptors (methods 316are also descriptors). 317 318Note: 319 320 If your enumeration defines ``__new__`` and/or ``__init__`` then 321 whatever value(s) were given to the enum member will be passed into 322 those methods. See `Planet`_ for an example. 323 324 325Restricted subclassing of enumerations 326-------------------------------------- 327 328Subclassing an enumeration is allowed only if the enumeration does not define 329any members. So this is forbidden:: 330 331 >>> class MoreColor(Color): 332 ... pink = 17 333 Traceback (most recent call last): 334 ... 335 TypeError: Cannot extend enumerations 336 337But this is allowed:: 338 339 >>> class Foo(Enum): 340 ... def some_behavior(self): 341 ... pass 342 ... 343 >>> class Bar(Foo): 344 ... happy = 1 345 ... sad = 2 346 ... 347 348Allowing subclassing of enums that define members would lead to a violation of 349some important invariants of types and instances. On the other hand, it makes 350sense to allow sharing some common behavior between a group of enumerations. 351(See `OrderedEnum`_ for an example.) 352 353 354Pickling 355-------- 356 357Enumerations can be pickled and unpickled:: 358 359 >>> from enum.test_enum import Fruit 360 >>> from pickle import dumps, loads 361 >>> Fruit.tomato is loads(dumps(Fruit.tomato, 2)) 362 True 363 364The usual restrictions for pickling apply: picklable enums must be defined in 365the top level of a module, since unpickling requires them to be importable 366from that module. 367 368Note: 369 370 With pickle protocol version 4 (introduced in Python 3.4) it is possible 371 to easily pickle enums nested in other classes. 372 373 374 375Functional API 376-------------- 377 378The ``Enum`` class is callable, providing the following functional API:: 379 380 >>> Animal = Enum('Animal', 'ant bee cat dog') 381 >>> Animal 382 <enum 'Animal'> 383 >>> Animal.ant 384 <Animal.ant: 1> 385 >>> Animal.ant.value 386 1 387 >>> list(Animal) 388 [<Animal.ant: 1>, <Animal.bee: 2>, <Animal.cat: 3>, <Animal.dog: 4>] 389 390The semantics of this API resemble ``namedtuple``. The first argument 391of the call to ``Enum`` is the name of the enumeration. 392 393The second argument is the *source* of enumeration member names. It can be a 394whitespace-separated string of names, a sequence of names, a sequence of 3952-tuples with key/value pairs, or a mapping (e.g. dictionary) of names to 396values. The last two options enable assigning arbitrary values to 397enumerations; the others auto-assign increasing integers starting with 1. A 398new class derived from ``Enum`` is returned. In other words, the above 399assignment to ``Animal`` is equivalent to:: 400 401 >>> class Animals(Enum): 402 ... ant = 1 403 ... bee = 2 404 ... cat = 3 405 ... dog = 4 406 407Pickling enums created with the functional API can be tricky as frame stack 408implementation details are used to try and figure out which module the 409enumeration is being created in (e.g. it will fail if you use a utility 410function in separate module, and also may not work on IronPython or Jython). 411The solution is to specify the module name explicitly as follows:: 412 413 >>> Animals = Enum('Animals', 'ant bee cat dog', module=__name__) 414 415Derived Enumerations 416-------------------- 417 418IntEnum 419^^^^^^^ 420 421A variation of ``Enum`` is provided which is also a subclass of 422``int``. Members of an ``IntEnum`` can be compared to integers; 423by extension, integer enumerations of different types can also be compared 424to each other:: 425 426 >>> from enum import IntEnum 427 >>> class Shape(IntEnum): 428 ... circle = 1 429 ... square = 2 430 ... 431 >>> class Request(IntEnum): 432 ... post = 1 433 ... get = 2 434 ... 435 >>> Shape == 1 436 False 437 >>> Shape.circle == 1 438 True 439 >>> Shape.circle == Request.post 440 True 441 442However, they still can't be compared to standard ``Enum`` enumerations:: 443 444 >>> class Shape(IntEnum): 445 ... circle = 1 446 ... square = 2 447 ... 448 >>> class Color(Enum): 449 ... red = 1 450 ... green = 2 451 ... 452 >>> Shape.circle == Color.red 453 False 454 455``IntEnum`` values behave like integers in other ways you'd expect:: 456 457 >>> int(Shape.circle) 458 1 459 >>> ['a', 'b', 'c'][Shape.circle] 460 'b' 461 >>> [i for i in range(Shape.square)] 462 [0, 1] 463 464For the vast majority of code, ``Enum`` is strongly recommended, 465since ``IntEnum`` breaks some semantic promises of an enumeration (by 466being comparable to integers, and thus by transitivity to other 467unrelated enumerations). It should be used only in special cases where 468there's no other choice; for example, when integer constants are 469replaced with enumerations and backwards compatibility is required with code 470that still expects integers. 471 472 473Others 474^^^^^^ 475 476While ``IntEnum`` is part of the ``enum`` module, it would be very 477simple to implement independently:: 478 479 class IntEnum(int, Enum): 480 pass 481 482This demonstrates how similar derived enumerations can be defined; for example 483a ``StrEnum`` that mixes in ``str`` instead of ``int``. 484 485Some rules: 486 4871. When subclassing ``Enum``, mix-in types must appear before 488 ``Enum`` itself in the sequence of bases, as in the ``IntEnum`` 489 example above. 4902. While ``Enum`` can have members of any type, once you mix in an 491 additional type, all the members must have values of that type, e.g. 492 ``int`` above. This restriction does not apply to mix-ins which only 493 add methods and don't specify another data type such as ``int`` or 494 ``str``. 4953. When another data type is mixed in, the ``value`` attribute is *not the 496 same* as the enum member itself, although it is equivalant and will compare 497 equal. 4984. %-style formatting: ``%s`` and ``%r`` call ``Enum``'s ``__str__`` and 499 ``__repr__`` respectively; other codes (such as ``%i`` or ``%h`` for 500 IntEnum) treat the enum member as its mixed-in type. 501 502 Note: Prior to Python 3.4 there is a bug in ``str``'s %-formatting: ``int`` 503 subclasses are printed as strings and not numbers when the ``%d``, ``%i``, 504 or ``%u`` codes are used. 5055. ``str.__format__`` (or ``format``) will use the mixed-in 506 type's ``__format__``. If the ``Enum``'s ``str`` or 507 ``repr`` is desired use the ``!s`` or ``!r`` ``str`` format codes. 508 509 510Decorators 511---------- 512 513unique 514^^^^^^ 515 516A ``class`` decorator specifically for enumerations. It searches an 517enumeration's ``__members__`` gathering any aliases it finds; if any are 518found ``ValueError`` is raised with the details:: 519 520 >>> @unique 521 ... class NoDupes(Enum): 522 ... first = 'one' 523 ... second = 'two' 524 ... third = 'two' 525 Traceback (most recent call last): 526 ... 527 ValueError: duplicate names found in <enum 'NoDupes'>: third -> second 528 529 530Interesting examples 531-------------------- 532 533While ``Enum`` and ``IntEnum`` are expected to cover the majority of 534use-cases, they cannot cover them all. Here are recipes for some different 535types of enumerations that can be used directly, or as examples for creating 536one's own. 537 538 539AutoNumber 540^^^^^^^^^^ 541 542Avoids having to specify the value for each enumeration member:: 543 544 >>> class AutoNumber(Enum): 545 ... def __new__(cls): 546 ... value = len(cls.__members__) + 1 547 ... obj = object.__new__(cls) 548 ... obj._value_ = value 549 ... return obj 550 ... 551 >>> class Color(AutoNumber): 552 ... __order__ = "red green blue" # only needed in 2.x 553 ... red = () 554 ... green = () 555 ... blue = () 556 ... 557 >>> Color.green.value == 2 558 True 559 560Note: 561 562 The `__new__` method, if defined, is used during creation of the Enum 563 members; it is then replaced by Enum's `__new__` which is used after 564 class creation for lookup of existing members. Due to the way Enums are 565 supposed to behave, there is no way to customize Enum's `__new__`. 566 567 568UniqueEnum 569^^^^^^^^^^ 570 571Raises an error if a duplicate member name is found instead of creating an 572alias:: 573 574 >>> class UniqueEnum(Enum): 575 ... def __init__(self, *args): 576 ... cls = self.__class__ 577 ... if any(self.value == e.value for e in cls): 578 ... a = self.name 579 ... e = cls(self.value).name 580 ... raise ValueError( 581 ... "aliases not allowed in UniqueEnum: %r --> %r" 582 ... % (a, e)) 583 ... 584 >>> class Color(UniqueEnum): 585 ... red = 1 586 ... green = 2 587 ... blue = 3 588 ... grene = 2 589 Traceback (most recent call last): 590 ... 591 ValueError: aliases not allowed in UniqueEnum: 'grene' --> 'green' 592 593 594OrderedEnum 595^^^^^^^^^^^ 596 597An ordered enumeration that is not based on ``IntEnum`` and so maintains 598the normal ``Enum`` invariants (such as not being comparable to other 599enumerations):: 600 601 >>> class OrderedEnum(Enum): 602 ... def __ge__(self, other): 603 ... if self.__class__ is other.__class__: 604 ... return self._value_ >= other._value_ 605 ... return NotImplemented 606 ... def __gt__(self, other): 607 ... if self.__class__ is other.__class__: 608 ... return self._value_ > other._value_ 609 ... return NotImplemented 610 ... def __le__(self, other): 611 ... if self.__class__ is other.__class__: 612 ... return self._value_ <= other._value_ 613 ... return NotImplemented 614 ... def __lt__(self, other): 615 ... if self.__class__ is other.__class__: 616 ... return self._value_ < other._value_ 617 ... return NotImplemented 618 ... 619 >>> class Grade(OrderedEnum): 620 ... __ordered__ = 'A B C D F' 621 ... A = 5 622 ... B = 4 623 ... C = 3 624 ... D = 2 625 ... F = 1 626 ... 627 >>> Grade.C < Grade.A 628 True 629 630 631Planet 632^^^^^^ 633 634If ``__new__`` or ``__init__`` is defined the value of the enum member 635will be passed to those methods:: 636 637 >>> class Planet(Enum): 638 ... MERCURY = (3.303e+23, 2.4397e6) 639 ... VENUS = (4.869e+24, 6.0518e6) 640 ... EARTH = (5.976e+24, 6.37814e6) 641 ... MARS = (6.421e+23, 3.3972e6) 642 ... JUPITER = (1.9e+27, 7.1492e7) 643 ... SATURN = (5.688e+26, 6.0268e7) 644 ... URANUS = (8.686e+25, 2.5559e7) 645 ... NEPTUNE = (1.024e+26, 2.4746e7) 646 ... def __init__(self, mass, radius): 647 ... self.mass = mass # in kilograms 648 ... self.radius = radius # in meters 649 ... @property 650 ... def surface_gravity(self): 651 ... # universal gravitational constant (m3 kg-1 s-2) 652 ... G = 6.67300E-11 653 ... return G * self.mass / (self.radius * self.radius) 654 ... 655 >>> Planet.EARTH.value 656 (5.976e+24, 6378140.0) 657 >>> Planet.EARTH.surface_gravity 658 9.802652743337129 659 660 661How are Enums different? 662------------------------ 663 664Enums have a custom metaclass that affects many aspects of both derived Enum 665classes and their instances (members). 666 667 668Enum Classes 669^^^^^^^^^^^^ 670 671The ``EnumMeta`` metaclass is responsible for providing the 672``__contains__``, ``__dir__``, ``__iter__`` and other methods that 673allow one to do things with an ``Enum`` class that fail on a typical 674class, such as ``list(Color)`` or ``some_var in Color``. ``EnumMeta`` is 675responsible for ensuring that various other methods on the final ``Enum`` 676class are correct (such as ``__new__``, ``__getnewargs__``, 677``__str__`` and ``__repr__``). 678 679.. note:: 680 681 ``__dir__`` is not changed in the Python 2 line as it messes up some 682 of the decorators included in the stdlib. 683 684 685Enum Members (aka instances) 686^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 687 688The most interesting thing about Enum members is that they are singletons. 689``EnumMeta`` creates them all while it is creating the ``Enum`` 690class itself, and then puts a custom ``__new__`` in place to ensure 691that no new ones are ever instantiated by returning only the existing 692member instances. 693 694 695Finer Points 696^^^^^^^^^^^^ 697 698``Enum`` members are instances of an ``Enum`` class, and even though they 699are accessible as `EnumClass.member1.member2`, they should not be 700accessed directly from the member as that lookup may fail or, worse, 701return something besides the ``Enum`` member you were looking for 702(changed in version 1.1.1):: 703 704 >>> class FieldTypes(Enum): 705 ... name = 1 706 ... value = 2 707 ... size = 3 708 ... 709 >>> FieldTypes.value.size 710 <FieldTypes.size: 3> 711 >>> FieldTypes.size.value 712 3 713 714The ``__members__`` attribute is only available on the class. 715 716In Python 3.x ``__members__`` is always an ``OrderedDict``, with the order being 717the definition order. In Python 2.7 ``__members__`` is an ``OrderedDict`` if 718``__order__`` was specified, and a plain ``dict`` otherwise. In all other Python 7192.x versions ``__members__`` is a plain ``dict`` even if ``__order__`` was specified 720as the ``OrderedDict`` type didn't exist yet. 721 722If you give your ``Enum`` subclass extra methods, like the `Planet`_ 723class above, those methods will show up in a `dir` of the member, 724but not of the class:: 725 726 >>> dir(Planet) 727 ['EARTH', 'JUPITER', 'MARS', 'MERCURY', 'NEPTUNE', 'SATURN', 'URANUS', 728 'VENUS', '__class__', '__doc__', '__members__', '__module__'] 729 >>> dir(Planet.EARTH) 730 ['__class__', '__doc__', '__module__', 'name', 'surface_gravity', 'value'] 731 732A ``__new__`` method will only be used for the creation of the 733``Enum`` members -- after that it is replaced. This means if you wish to 734change how ``Enum`` members are looked up you either have to write a 735helper function or a ``classmethod``. 736