annotate Lib/enum.py @ 87690:66c1c9f32567 default tip

Add use_weakref option to functools.lru_cache The use_weakref option makes lru_cache create weak references to the function arguments when creating the cache key, which prevents them from staying in the memory forever even after all other references to them are gone. This is a proof of concept for http://bugs.python.org/issue19859
author Radomir Dopieralski <devel@sheep.art.pl>
date Tue, 03 Dec 2013 16:02:48 +0100
parents ca909a3728d3
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
84130
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
1 import sys
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
2 from collections import OrderedDict
85796
436b606ecfe8 Close #19030: improvements to inspect and Enum.
Ethan Furman <ethan@stoneleaf.us>
parents: 85790
diff changeset
3 from types import MappingProxyType, DynamicClassAttribute
84130
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
4
84713
2079a517193b closes issue18042 -- a `unique` decorator is added to enum.py
Ethan Furman <ethan@stoneleaf.us>
parents: 84130
diff changeset
5 __all__ = ['Enum', 'IntEnum', 'unique']
84130
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
6
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
7
85717
54ddd1124df8 Close #18989: enum members will no longer overwrite other attributes, nor be overwritten by them.
Ethan Furman <ethan@stoneleaf.us>
parents: 85707
diff changeset
8 def _is_descriptor(obj):
54ddd1124df8 Close #18989: enum members will no longer overwrite other attributes, nor be overwritten by them.
Ethan Furman <ethan@stoneleaf.us>
parents: 85707
diff changeset
9 """Returns True if obj is a descriptor, False otherwise."""
54ddd1124df8 Close #18989: enum members will no longer overwrite other attributes, nor be overwritten by them.
Ethan Furman <ethan@stoneleaf.us>
parents: 85707
diff changeset
10 return (
54ddd1124df8 Close #18989: enum members will no longer overwrite other attributes, nor be overwritten by them.
Ethan Furman <ethan@stoneleaf.us>
parents: 85707
diff changeset
11 hasattr(obj, '__get__') or
54ddd1124df8 Close #18989: enum members will no longer overwrite other attributes, nor be overwritten by them.
Ethan Furman <ethan@stoneleaf.us>
parents: 85707
diff changeset
12 hasattr(obj, '__set__') or
54ddd1124df8 Close #18989: enum members will no longer overwrite other attributes, nor be overwritten by them.
Ethan Furman <ethan@stoneleaf.us>
parents: 85707
diff changeset
13 hasattr(obj, '__delete__'))
54ddd1124df8 Close #18989: enum members will no longer overwrite other attributes, nor be overwritten by them.
Ethan Furman <ethan@stoneleaf.us>
parents: 85707
diff changeset
14
54ddd1124df8 Close #18989: enum members will no longer overwrite other attributes, nor be overwritten by them.
Ethan Furman <ethan@stoneleaf.us>
parents: 85707
diff changeset
15
84130
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
16 def _is_dunder(name):
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
17 """Returns True if a __dunder__ name, False otherwise."""
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
18 return (name[:2] == name[-2:] == '__' and
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
19 name[2:3] != '_' and
86139
516576f5f9dc Close #19156: add tests and fix for Enum helper edge cases. Patch from CliffM.
Ethan Furman <ethan@stoneleaf.us>
parents: 85816
diff changeset
20 name[-3:-2] != '_' and
516576f5f9dc Close #19156: add tests and fix for Enum helper edge cases. Patch from CliffM.
Ethan Furman <ethan@stoneleaf.us>
parents: 85816
diff changeset
21 len(name) > 4)
84130
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
22
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
23
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
24 def _is_sunder(name):
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
25 """Returns True if a _sunder_ name, False otherwise."""
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
26 return (name[0] == name[-1] == '_' and
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
27 name[1:2] != '_' and
86139
516576f5f9dc Close #19156: add tests and fix for Enum helper edge cases. Patch from CliffM.
Ethan Furman <ethan@stoneleaf.us>
parents: 85816
diff changeset
28 name[-2:-1] != '_' and
516576f5f9dc Close #19156: add tests and fix for Enum helper edge cases. Patch from CliffM.
Ethan Furman <ethan@stoneleaf.us>
parents: 85816
diff changeset
29 len(name) > 2)
84130
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
30
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
31
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
32 def _make_class_unpicklable(cls):
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
33 """Make the given class un-picklable."""
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
34 def _break_on_call_reduce(self):
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
35 raise TypeError('%r cannot be pickled' % self)
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
36 cls.__reduce__ = _break_on_call_reduce
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
37 cls.__module__ = '<unknown>'
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
38
85717
54ddd1124df8 Close #18989: enum members will no longer overwrite other attributes, nor be overwritten by them.
Ethan Furman <ethan@stoneleaf.us>
parents: 85707
diff changeset
39
84130
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
40 class _EnumDict(dict):
85717
54ddd1124df8 Close #18989: enum members will no longer overwrite other attributes, nor be overwritten by them.
Ethan Furman <ethan@stoneleaf.us>
parents: 85707
diff changeset
41 """Track enum member order and ensure member names are not reused.
84130
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
42
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
43 EnumMeta will use the names found in self._member_names as the
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
44 enumeration member names.
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
45
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
46 """
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
47 def __init__(self):
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
48 super().__init__()
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
49 self._member_names = []
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
50
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
51 def __setitem__(self, key, value):
85717
54ddd1124df8 Close #18989: enum members will no longer overwrite other attributes, nor be overwritten by them.
Ethan Furman <ethan@stoneleaf.us>
parents: 85707
diff changeset
52 """Changes anything not dundered or not a descriptor.
84130
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
53
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
54 If an enum member name is used twice, an error is raised; duplicate
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
55 values are not checked for.
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
56
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
57 Single underscore (sunder) names are reserved.
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
58
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
59 """
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
60 if _is_sunder(key):
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
61 raise ValueError('_names_ are reserved for future Enum use')
85717
54ddd1124df8 Close #18989: enum members will no longer overwrite other attributes, nor be overwritten by them.
Ethan Furman <ethan@stoneleaf.us>
parents: 85707
diff changeset
62 elif _is_dunder(key):
54ddd1124df8 Close #18989: enum members will no longer overwrite other attributes, nor be overwritten by them.
Ethan Furman <ethan@stoneleaf.us>
parents: 85707
diff changeset
63 pass
54ddd1124df8 Close #18989: enum members will no longer overwrite other attributes, nor be overwritten by them.
Ethan Furman <ethan@stoneleaf.us>
parents: 85707
diff changeset
64 elif key in self._member_names:
54ddd1124df8 Close #18989: enum members will no longer overwrite other attributes, nor be overwritten by them.
Ethan Furman <ethan@stoneleaf.us>
parents: 85707
diff changeset
65 # descriptor overwriting an enum?
54ddd1124df8 Close #18989: enum members will no longer overwrite other attributes, nor be overwritten by them.
Ethan Furman <ethan@stoneleaf.us>
parents: 85707
diff changeset
66 raise TypeError('Attempted to reuse key: %r' % key)
54ddd1124df8 Close #18989: enum members will no longer overwrite other attributes, nor be overwritten by them.
Ethan Furman <ethan@stoneleaf.us>
parents: 85707
diff changeset
67 elif not _is_descriptor(value):
54ddd1124df8 Close #18989: enum members will no longer overwrite other attributes, nor be overwritten by them.
Ethan Furman <ethan@stoneleaf.us>
parents: 85707
diff changeset
68 if key in self:
54ddd1124df8 Close #18989: enum members will no longer overwrite other attributes, nor be overwritten by them.
Ethan Furman <ethan@stoneleaf.us>
parents: 85707
diff changeset
69 # enum overwriting a descriptor?
54ddd1124df8 Close #18989: enum members will no longer overwrite other attributes, nor be overwritten by them.
Ethan Furman <ethan@stoneleaf.us>
parents: 85707
diff changeset
70 raise TypeError('Key already defined as: %r' % self[key])
84130
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
71 self._member_names.append(key)
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
72 super().__setitem__(key, value)
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
73
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
74
85717
54ddd1124df8 Close #18989: enum members will no longer overwrite other attributes, nor be overwritten by them.
Ethan Furman <ethan@stoneleaf.us>
parents: 85707
diff changeset
75
85222
a9ee869cae40 #18705: merge with 3.3.
Ezio Melotti <ezio.melotti@gmail.com>
parents: 85127
diff changeset
76 # Dummy value for Enum as EnumMeta explicitly checks for it, but of course
a9ee869cae40 #18705: merge with 3.3.
Ezio Melotti <ezio.melotti@gmail.com>
parents: 85127
diff changeset
77 # until EnumMeta finishes running the first time the Enum class doesn't exist.
a9ee869cae40 #18705: merge with 3.3.
Ezio Melotti <ezio.melotti@gmail.com>
parents: 85127
diff changeset
78 # This is also why there are checks in EnumMeta like `if Enum is not None`
84130
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
79 Enum = None
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
80
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
81
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
82 class EnumMeta(type):
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
83 """Metaclass for Enum"""
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
84 @classmethod
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
85 def __prepare__(metacls, cls, bases):
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
86 return _EnumDict()
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
87
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
88 def __new__(metacls, cls, bases, classdict):
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
89 # an Enum class is final once enumeration items have been defined; it
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
90 # cannot be mixed with other types (int, float, etc.) if it has an
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
91 # inherited __new__ unless a new __new__ is defined (or the resulting
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
92 # class will fail).
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
93 member_type, first_enum = metacls._get_mixins_(bases)
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
94 __new__, save_new, use_args = metacls._find_new_(classdict, member_type,
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
95 first_enum)
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
96
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
97 # save enum items into separate mapping so they don't get baked into
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
98 # the new class
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
99 members = {k: classdict[k] for k in classdict._member_names}
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
100 for name in classdict._member_names:
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
101 del classdict[name]
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
102
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
103 # check for illegal enum names (any others?)
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
104 invalid_names = set(members) & {'mro', }
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
105 if invalid_names:
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
106 raise ValueError('Invalid enum member name: {0}'.format(
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
107 ','.join(invalid_names)))
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
108
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
109 # create our new Enum type
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
110 enum_class = super().__new__(metacls, cls, bases, classdict)
84721
511c4daac102 Change _names to _names_ since the latter is reserved for Enum use.
Ethan Furman <ethan@stoneleaf.us>
parents: 84720
diff changeset
111 enum_class._member_names_ = [] # names in definition order
511c4daac102 Change _names to _names_ since the latter is reserved for Enum use.
Ethan Furman <ethan@stoneleaf.us>
parents: 84720
diff changeset
112 enum_class._member_map_ = OrderedDict() # name->value map
85021
b034418e840b Close #18635: Move class level private attribute from instance to class.
Ethan Furman <ethan@stoneleaf.us>
parents: 84826
diff changeset
113 enum_class._member_type_ = member_type
84130
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
114
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
115 # Reverse value->name map for hashable values.
84721
511c4daac102 Change _names to _names_ since the latter is reserved for Enum use.
Ethan Furman <ethan@stoneleaf.us>
parents: 84720
diff changeset
116 enum_class._value2member_map_ = {}
84130
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
117
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
118 # check for a __getnewargs__, and if not present sabotage
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
119 # pickling, since it won't work anyway
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
120 if (member_type is not object and
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
121 member_type.__dict__.get('__getnewargs__') is None
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
122 ):
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
123 _make_class_unpicklable(enum_class)
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
124
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
125 # instantiate them, checking for duplicates as we go
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
126 # we instantiate first instead of checking for duplicates first in case
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
127 # a custom __new__ is doing something funky with the values -- such as
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
128 # auto-numbering ;)
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
129 for member_name in classdict._member_names:
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
130 value = members[member_name]
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
131 if not isinstance(value, tuple):
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
132 args = (value, )
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
133 else:
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
134 args = value
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
135 if member_type is tuple: # special case for tuple enums
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
136 args = (args, ) # wrap it one more time
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
137 if not use_args:
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
138 enum_member = __new__(enum_class)
84826
95e1d0efd896 Close #18545: now only executes member_type if no _value_ is assigned in __new__.
Ethan Furman <ethan@stoneleaf.us>
parents: 84721
diff changeset
139 if not hasattr(enum_member, '_value_'):
95e1d0efd896 Close #18545: now only executes member_type if no _value_ is assigned in __new__.
Ethan Furman <ethan@stoneleaf.us>
parents: 84721
diff changeset
140 enum_member._value_ = value
84130
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
141 else:
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
142 enum_member = __new__(enum_class, *args)
84826
95e1d0efd896 Close #18545: now only executes member_type if no _value_ is assigned in __new__.
Ethan Furman <ethan@stoneleaf.us>
parents: 84721
diff changeset
143 if not hasattr(enum_member, '_value_'):
95e1d0efd896 Close #18545: now only executes member_type if no _value_ is assigned in __new__.
Ethan Furman <ethan@stoneleaf.us>
parents: 84721
diff changeset
144 enum_member._value_ = member_type(*args)
84721
511c4daac102 Change _names to _names_ since the latter is reserved for Enum use.
Ethan Furman <ethan@stoneleaf.us>
parents: 84720
diff changeset
145 value = enum_member._value_
511c4daac102 Change _names to _names_ since the latter is reserved for Enum use.
Ethan Furman <ethan@stoneleaf.us>
parents: 84720
diff changeset
146 enum_member._name_ = member_name
85724
353ced6ae182 Close #18693: Enum is now more help() friendly.
Ethan Furman <ethan@stoneleaf.us>
parents: 85717
diff changeset
147 enum_member.__objclass__ = enum_class
84130
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
148 enum_member.__init__(*args)
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
149 # If another member with the same value was already defined, the
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
150 # new member becomes an alias to the existing one.
84721
511c4daac102 Change _names to _names_ since the latter is reserved for Enum use.
Ethan Furman <ethan@stoneleaf.us>
parents: 84720
diff changeset
151 for name, canonical_member in enum_class._member_map_.items():
511c4daac102 Change _names to _names_ since the latter is reserved for Enum use.
Ethan Furman <ethan@stoneleaf.us>
parents: 84720
diff changeset
152 if canonical_member.value == enum_member._value_:
84130
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
153 enum_member = canonical_member
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
154 break
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
155 else:
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
156 # Aliases don't appear in member names (only in __members__).
84721
511c4daac102 Change _names to _names_ since the latter is reserved for Enum use.
Ethan Furman <ethan@stoneleaf.us>
parents: 84720
diff changeset
157 enum_class._member_names_.append(member_name)
511c4daac102 Change _names to _names_ since the latter is reserved for Enum use.
Ethan Furman <ethan@stoneleaf.us>
parents: 84720
diff changeset
158 enum_class._member_map_[member_name] = enum_member
84130
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
159 try:
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
160 # This may fail if value is not hashable. We can't add the value
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
161 # to the map, and by-value lookups for this value will be
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
162 # linear.
84721
511c4daac102 Change _names to _names_ since the latter is reserved for Enum use.
Ethan Furman <ethan@stoneleaf.us>
parents: 84720
diff changeset
163 enum_class._value2member_map_[value] = enum_member
84130
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
164 except TypeError:
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
165 pass
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
166
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
167 # double check that repr and friends are not the mixin's or various
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
168 # things break (such as pickle)
85485
058cb219b3b5 Close #18738: Route __format__ calls to mixed-in type for mixed Enums (such as IntEnum).
Ethan Furman <ethan@stoneleaf.us>
parents: 85222
diff changeset
169 for name in ('__repr__', '__str__', '__format__', '__getnewargs__'):
84130
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
170 class_method = getattr(enum_class, name)
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
171 obj_method = getattr(member_type, name, None)
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
172 enum_method = getattr(first_enum, name, None)
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
173 if obj_method is not None and obj_method is class_method:
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
174 setattr(enum_class, name, enum_method)
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
175
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
176 # replace any other __new__ with our own (as long as Enum is not None,
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
177 # anyway) -- again, this is to support pickle
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
178 if Enum is not None:
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
179 # if the user defined their own __new__, save it before it gets
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
180 # clobbered in case they subclass later
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
181 if save_new:
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
182 enum_class.__new_member__ = __new__
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
183 enum_class.__new__ = Enum.__new__
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
184 return enum_class
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
185
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
186 def __call__(cls, value, names=None, *, module=None, type=None):
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
187 """Either returns an existing member, or creates a new enum class.
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
188
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
189 This method is used both when an enum class is given a value to match
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
190 to an enumeration member (i.e. Color(3)) and for the functional API
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
191 (i.e. Color = Enum('Color', names='red green blue')).
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
192
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
193 When used for the functional API: `module`, if set, will be stored in
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
194 the new class' __module__ attribute; `type`, if set, will be mixed in
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
195 as the first base class.
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
196
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
197 Note: if `module` is not set this routine will attempt to discover the
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
198 calling module by walking the frame stack; if this is unsuccessful
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
199 the resulting class will not be pickleable.
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
200
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
201 """
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
202 if names is None: # simple value lookup
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
203 return cls.__new__(cls, value)
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
204 # otherwise, functional API: we're creating a new Enum type
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
205 return cls._create_(value, names, module=module, type=type)
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
206
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
207 def __contains__(cls, member):
84721
511c4daac102 Change _names to _names_ since the latter is reserved for Enum use.
Ethan Furman <ethan@stoneleaf.us>
parents: 84720
diff changeset
208 return isinstance(member, cls) and member.name in cls._member_map_
84130
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
209
85790
ed011b0d7daf Close #19025: Better error message when trying to delete an Enum member.
Ethan Furman <ethan@stoneleaf.us>
parents: 85724
diff changeset
210 def __delattr__(cls, attr):
ed011b0d7daf Close #19025: Better error message when trying to delete an Enum member.
Ethan Furman <ethan@stoneleaf.us>
parents: 85724
diff changeset
211 # nicer error message when someone tries to delete an attribute
ed011b0d7daf Close #19025: Better error message when trying to delete an Enum member.
Ethan Furman <ethan@stoneleaf.us>
parents: 85724
diff changeset
212 # (see issue19025).
ed011b0d7daf Close #19025: Better error message when trying to delete an Enum member.
Ethan Furman <ethan@stoneleaf.us>
parents: 85724
diff changeset
213 if attr in cls._member_map_:
ed011b0d7daf Close #19025: Better error message when trying to delete an Enum member.
Ethan Furman <ethan@stoneleaf.us>
parents: 85724
diff changeset
214 raise AttributeError(
ed011b0d7daf Close #19025: Better error message when trying to delete an Enum member.
Ethan Furman <ethan@stoneleaf.us>
parents: 85724
diff changeset
215 "%s: cannot delete Enum member." % cls.__name__)
ed011b0d7daf Close #19025: Better error message when trying to delete an Enum member.
Ethan Furman <ethan@stoneleaf.us>
parents: 85724
diff changeset
216 super().__delattr__(attr)
ed011b0d7daf Close #19025: Better error message when trying to delete an Enum member.
Ethan Furman <ethan@stoneleaf.us>
parents: 85724
diff changeset
217
85127
39697dcd97e3 Issue 18693: Put custom __dir__ back in place. Will instead look at fixing `help()`.
Ethan Furman <ethan@stoneleaf.us>
parents: 85104
diff changeset
218 def __dir__(self):
85790
ed011b0d7daf Close #19025: Better error message when trying to delete an Enum member.
Ethan Furman <ethan@stoneleaf.us>
parents: 85724
diff changeset
219 return (['__class__', '__doc__', '__members__', '__module__'] +
ed011b0d7daf Close #19025: Better error message when trying to delete an Enum member.
Ethan Furman <ethan@stoneleaf.us>
parents: 85724
diff changeset
220 self._member_names_)
85127
39697dcd97e3 Issue 18693: Put custom __dir__ back in place. Will instead look at fixing `help()`.
Ethan Furman <ethan@stoneleaf.us>
parents: 85104
diff changeset
221
84130
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
222 def __getattr__(cls, name):
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
223 """Return the enum member matching `name`
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
224
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
225 We use __getattr__ instead of descriptors or inserting into the enum
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
226 class' __dict__ in order to support `name` and `value` being both
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
227 properties for enum members (which live in the class' __dict__) and
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
228 enum members themselves.
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
229
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
230 """
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
231 if _is_dunder(name):
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
232 raise AttributeError(name)
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
233 try:
84721
511c4daac102 Change _names to _names_ since the latter is reserved for Enum use.
Ethan Furman <ethan@stoneleaf.us>
parents: 84720
diff changeset
234 return cls._member_map_[name]
84130
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
235 except KeyError:
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
236 raise AttributeError(name) from None
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
237
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
238 def __getitem__(cls, name):
84721
511c4daac102 Change _names to _names_ since the latter is reserved for Enum use.
Ethan Furman <ethan@stoneleaf.us>
parents: 84720
diff changeset
239 return cls._member_map_[name]
84130
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
240
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
241 def __iter__(cls):
84721
511c4daac102 Change _names to _names_ since the latter is reserved for Enum use.
Ethan Furman <ethan@stoneleaf.us>
parents: 84720
diff changeset
242 return (cls._member_map_[name] for name in cls._member_names_)
84130
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
243
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
244 def __len__(cls):
84721
511c4daac102 Change _names to _names_ since the latter is reserved for Enum use.
Ethan Furman <ethan@stoneleaf.us>
parents: 84720
diff changeset
245 return len(cls._member_names_)
84130
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
246
85707
24aa6f98fe25 Add __reversed__ to Enum. Minor code reorg (moved __members__ to be in alpha order).
Ethan Furman <ethan@stoneleaf.us>
parents: 85574
diff changeset
247 @property
24aa6f98fe25 Add __reversed__ to Enum. Minor code reorg (moved __members__ to be in alpha order).
Ethan Furman <ethan@stoneleaf.us>
parents: 85574
diff changeset
248 def __members__(cls):
24aa6f98fe25 Add __reversed__ to Enum. Minor code reorg (moved __members__ to be in alpha order).
Ethan Furman <ethan@stoneleaf.us>
parents: 85574
diff changeset
249 """Returns a mapping of member name->value.
24aa6f98fe25 Add __reversed__ to Enum. Minor code reorg (moved __members__ to be in alpha order).
Ethan Furman <ethan@stoneleaf.us>
parents: 85574
diff changeset
250
24aa6f98fe25 Add __reversed__ to Enum. Minor code reorg (moved __members__ to be in alpha order).
Ethan Furman <ethan@stoneleaf.us>
parents: 85574
diff changeset
251 This mapping lists all enum members, including aliases. Note that this
24aa6f98fe25 Add __reversed__ to Enum. Minor code reorg (moved __members__ to be in alpha order).
Ethan Furman <ethan@stoneleaf.us>
parents: 85574
diff changeset
252 is a read-only view of the internal mapping.
24aa6f98fe25 Add __reversed__ to Enum. Minor code reorg (moved __members__ to be in alpha order).
Ethan Furman <ethan@stoneleaf.us>
parents: 85574
diff changeset
253
24aa6f98fe25 Add __reversed__ to Enum. Minor code reorg (moved __members__ to be in alpha order).
Ethan Furman <ethan@stoneleaf.us>
parents: 85574
diff changeset
254 """
24aa6f98fe25 Add __reversed__ to Enum. Minor code reorg (moved __members__ to be in alpha order).
Ethan Furman <ethan@stoneleaf.us>
parents: 85574
diff changeset
255 return MappingProxyType(cls._member_map_)
24aa6f98fe25 Add __reversed__ to Enum. Minor code reorg (moved __members__ to be in alpha order).
Ethan Furman <ethan@stoneleaf.us>
parents: 85574
diff changeset
256
84130
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
257 def __repr__(cls):
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
258 return "<enum %r>" % cls.__name__
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
259
85707
24aa6f98fe25 Add __reversed__ to Enum. Minor code reorg (moved __members__ to be in alpha order).
Ethan Furman <ethan@stoneleaf.us>
parents: 85574
diff changeset
260 def __reversed__(cls):
24aa6f98fe25 Add __reversed__ to Enum. Minor code reorg (moved __members__ to be in alpha order).
Ethan Furman <ethan@stoneleaf.us>
parents: 85574
diff changeset
261 return (cls._member_map_[name] for name in reversed(cls._member_names_))
24aa6f98fe25 Add __reversed__ to Enum. Minor code reorg (moved __members__ to be in alpha order).
Ethan Furman <ethan@stoneleaf.us>
parents: 85574
diff changeset
262
85574
1d88d04aade2 Close #18924: Block naive attempts to change an Enum member.
Ethan Furman <ethan@stoneleaf.us>
parents: 85485
diff changeset
263 def __setattr__(cls, name, value):
1d88d04aade2 Close #18924: Block naive attempts to change an Enum member.
Ethan Furman <ethan@stoneleaf.us>
parents: 85485
diff changeset
264 """Block attempts to reassign Enum members.
1d88d04aade2 Close #18924: Block naive attempts to change an Enum member.
Ethan Furman <ethan@stoneleaf.us>
parents: 85485
diff changeset
265
1d88d04aade2 Close #18924: Block naive attempts to change an Enum member.
Ethan Furman <ethan@stoneleaf.us>
parents: 85485
diff changeset
266 A simple assignment to the class namespace only changes one of the
1d88d04aade2 Close #18924: Block naive attempts to change an Enum member.
Ethan Furman <ethan@stoneleaf.us>
parents: 85485
diff changeset
267 several possible ways to get an Enum member from the Enum class,
1d88d04aade2 Close #18924: Block naive attempts to change an Enum member.
Ethan Furman <ethan@stoneleaf.us>
parents: 85485
diff changeset
268 resulting in an inconsistent Enumeration.
1d88d04aade2 Close #18924: Block naive attempts to change an Enum member.
Ethan Furman <ethan@stoneleaf.us>
parents: 85485
diff changeset
269
1d88d04aade2 Close #18924: Block naive attempts to change an Enum member.
Ethan Furman <ethan@stoneleaf.us>
parents: 85485
diff changeset
270 """
1d88d04aade2 Close #18924: Block naive attempts to change an Enum member.
Ethan Furman <ethan@stoneleaf.us>
parents: 85485
diff changeset
271 member_map = cls.__dict__.get('_member_map_', {})
1d88d04aade2 Close #18924: Block naive attempts to change an Enum member.
Ethan Furman <ethan@stoneleaf.us>
parents: 85485
diff changeset
272 if name in member_map:
1d88d04aade2 Close #18924: Block naive attempts to change an Enum member.
Ethan Furman <ethan@stoneleaf.us>
parents: 85485
diff changeset
273 raise AttributeError('Cannot reassign members.')
1d88d04aade2 Close #18924: Block naive attempts to change an Enum member.
Ethan Furman <ethan@stoneleaf.us>
parents: 85485
diff changeset
274 super().__setattr__(name, value)
1d88d04aade2 Close #18924: Block naive attempts to change an Enum member.
Ethan Furman <ethan@stoneleaf.us>
parents: 85485
diff changeset
275
84130
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
276 def _create_(cls, class_name, names=None, *, module=None, type=None):
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
277 """Convenience method to create a new Enum class.
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
278
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
279 `names` can be:
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
280
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
281 * A string containing member names, separated either with spaces or
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
282 commas. Values are auto-numbered from 1.
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
283 * An iterable of member names. Values are auto-numbered from 1.
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
284 * An iterable of (member name, value) pairs.
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
285 * A mapping of member name -> value.
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
286
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
287 """
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
288 metacls = cls.__class__
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
289 bases = (cls, ) if type is None else (type, cls)
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
290 classdict = metacls.__prepare__(class_name, bases)
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
291
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
292 # special processing needed for names?
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
293 if isinstance(names, str):
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
294 names = names.replace(',', ' ').split()
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
295 if isinstance(names, (tuple, list)) and isinstance(names[0], str):
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
296 names = [(e, i) for (i, e) in enumerate(names, 1)]
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
297
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
298 # Here, names is either an iterable of (name, value) or a mapping.
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
299 for item in names:
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
300 if isinstance(item, str):
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
301 member_name, member_value = item, names[item]
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
302 else:
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
303 member_name, member_value = item
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
304 classdict[member_name] = member_value
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
305 enum_class = metacls.__new__(metacls, class_name, bases, classdict)
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
306
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
307 # TODO: replace the frame hack if a blessed way to know the calling
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
308 # module is ever developed
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
309 if module is None:
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
310 try:
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
311 module = sys._getframe(2).f_globals['__name__']
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
312 except (AttributeError, ValueError) as exc:
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
313 pass
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
314 if module is None:
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
315 _make_class_unpicklable(enum_class)
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
316 else:
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
317 enum_class.__module__ = module
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
318
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
319 return enum_class
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
320
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
321 @staticmethod
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
322 def _get_mixins_(bases):
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
323 """Returns the type for creating enum members, and the first inherited
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
324 enum class.
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
325
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
326 bases: the tuple of bases that was given to __new__
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
327
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
328 """
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
329 if not bases:
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
330 return object, Enum
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
331
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
332 # double check that we are not subclassing a class with existing
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
333 # enumeration members; while we're at it, see if any other data
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
334 # type has been mixed in so we can use the correct __new__
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
335 member_type = first_enum = None
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
336 for base in bases:
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
337 if (base is not Enum and
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
338 issubclass(base, Enum) and
84721
511c4daac102 Change _names to _names_ since the latter is reserved for Enum use.
Ethan Furman <ethan@stoneleaf.us>
parents: 84720
diff changeset
339 base._member_names_):
84130
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
340 raise TypeError("Cannot extend enumerations")
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
341 # base is now the last base in bases
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
342 if not issubclass(base, Enum):
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
343 raise TypeError("new enumerations must be created as "
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
344 "`ClassName([mixin_type,] enum_type)`")
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
345
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
346 # get correct mix-in type (either mix-in type of Enum subclass, or
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
347 # first base if last base is Enum)
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
348 if not issubclass(bases[0], Enum):
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
349 member_type = bases[0] # first data type
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
350 first_enum = bases[-1] # enum type
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
351 else:
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
352 for base in bases[0].__mro__:
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
353 # most common: (IntEnum, int, Enum, object)
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
354 # possible: (<Enum 'AutoIntEnum'>, <Enum 'IntEnum'>,
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
355 # <class 'int'>, <Enum 'Enum'>,
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
356 # <class 'object'>)
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
357 if issubclass(base, Enum):
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
358 if first_enum is None:
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
359 first_enum = base
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
360 else:
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
361 if member_type is None:
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
362 member_type = base
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
363
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
364 return member_type, first_enum
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
365
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
366 @staticmethod
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
367 def _find_new_(classdict, member_type, first_enum):
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
368 """Returns the __new__ to be used for creating the enum members.
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
369
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
370 classdict: the class dictionary given to __new__
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
371 member_type: the data type whose __new__ will be used by default
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
372 first_enum: enumeration to check for an overriding __new__
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
373
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
374 """
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
375 # now find the correct __new__, checking to see of one was defined
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
376 # by the user; also check earlier enum classes in case a __new__ was
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
377 # saved as __new_member__
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
378 __new__ = classdict.get('__new__', None)
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
379
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
380 # should __new__ be saved as __new_member__ later?
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
381 save_new = __new__ is not None
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
382
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
383 if __new__ is None:
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
384 # check all possibles for __new_member__ before falling back to
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
385 # __new__
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
386 for method in ('__new_member__', '__new__'):
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
387 for possible in (member_type, first_enum):
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
388 target = getattr(possible, method, None)
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
389 if target not in {
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
390 None,
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
391 None.__new__,
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
392 object.__new__,
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
393 Enum.__new__,
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
394 }:
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
395 __new__ = target
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
396 break
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
397 if __new__ is not None:
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
398 break
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
399 else:
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
400 __new__ = object.__new__
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
401
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
402 # if a non-object.__new__ is used then whatever value/tuple was
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
403 # assigned to the enum member name will be passed to __new__ and to the
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
404 # new enum member's __init__
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
405 if __new__ is object.__new__:
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
406 use_args = False
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
407 else:
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
408 use_args = True
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
409
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
410 return __new__, save_new, use_args
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
411
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
412
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
413 class Enum(metaclass=EnumMeta):
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
414 """Generic enumeration.
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
415
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
416 Derive from this class to define new enumerations.
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
417
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
418 """
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
419 def __new__(cls, value):
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
420 # all enum instances are actually created during class construction
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
421 # without calling this method; this method is called by the metaclass'
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
422 # __call__ (i.e. Color(3) ), and by pickle
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
423 if type(value) is cls:
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
424 # For lookups like Color(Color.red)
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
425 return value
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
426 # by-value search for a matching enum member
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
427 # see if it's in the reverse mapping (for hashable values)
84720
37c427e3eb94 Close #18508 -- fix _value2member_map to always have the member's value
Ethan Furman <ethan@stoneleaf.us>
parents: 84713
diff changeset
428 try:
84721
511c4daac102 Change _names to _names_ since the latter is reserved for Enum use.
Ethan Furman <ethan@stoneleaf.us>
parents: 84720
diff changeset
429 if value in cls._value2member_map_:
511c4daac102 Change _names to _names_ since the latter is reserved for Enum use.
Ethan Furman <ethan@stoneleaf.us>
parents: 84720
diff changeset
430 return cls._value2member_map_[value]
84720
37c427e3eb94 Close #18508 -- fix _value2member_map to always have the member's value
Ethan Furman <ethan@stoneleaf.us>
parents: 84713
diff changeset
431 except TypeError:
37c427e3eb94 Close #18508 -- fix _value2member_map to always have the member's value
Ethan Furman <ethan@stoneleaf.us>
parents: 84713
diff changeset
432 # not there, now do long search -- O(n) behavior
84721
511c4daac102 Change _names to _names_ since the latter is reserved for Enum use.
Ethan Furman <ethan@stoneleaf.us>
parents: 84720
diff changeset
433 for member in cls._member_map_.values():
84720
37c427e3eb94 Close #18508 -- fix _value2member_map to always have the member's value
Ethan Furman <ethan@stoneleaf.us>
parents: 84713
diff changeset
434 if member.value == value:
37c427e3eb94 Close #18508 -- fix _value2member_map to always have the member's value
Ethan Furman <ethan@stoneleaf.us>
parents: 84713
diff changeset
435 return member
84130
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
436 raise ValueError("%s is not a valid %s" % (value, cls.__name__))
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
437
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
438 def __repr__(self):
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
439 return "<%s.%s: %r>" % (
84721
511c4daac102 Change _names to _names_ since the latter is reserved for Enum use.
Ethan Furman <ethan@stoneleaf.us>
parents: 84720
diff changeset
440 self.__class__.__name__, self._name_, self._value_)
84130
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
441
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
442 def __str__(self):
84721
511c4daac102 Change _names to _names_ since the latter is reserved for Enum use.
Ethan Furman <ethan@stoneleaf.us>
parents: 84720
diff changeset
443 return "%s.%s" % (self.__class__.__name__, self._name_)
84130
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
444
85127
39697dcd97e3 Issue 18693: Put custom __dir__ back in place. Will instead look at fixing `help()`.
Ethan Furman <ethan@stoneleaf.us>
parents: 85104
diff changeset
445 def __dir__(self):
85724
353ced6ae182 Close #18693: Enum is now more help() friendly.
Ethan Furman <ethan@stoneleaf.us>
parents: 85717
diff changeset
446 added_behavior = [m for m in self.__class__.__dict__ if m[0] != '_']
85790
ed011b0d7daf Close #19025: Better error message when trying to delete an Enum member.
Ethan Furman <ethan@stoneleaf.us>
parents: 85724
diff changeset
447 return (['__class__', '__doc__', '__module__', 'name', 'value'] +
ed011b0d7daf Close #19025: Better error message when trying to delete an Enum member.
Ethan Furman <ethan@stoneleaf.us>
parents: 85724
diff changeset
448 added_behavior)
85127
39697dcd97e3 Issue 18693: Put custom __dir__ back in place. Will instead look at fixing `help()`.
Ethan Furman <ethan@stoneleaf.us>
parents: 85104
diff changeset
449
85485
058cb219b3b5 Close #18738: Route __format__ calls to mixed-in type for mixed Enums (such as IntEnum).
Ethan Furman <ethan@stoneleaf.us>
parents: 85222
diff changeset
450 def __format__(self, format_spec):
058cb219b3b5 Close #18738: Route __format__ calls to mixed-in type for mixed Enums (such as IntEnum).
Ethan Furman <ethan@stoneleaf.us>
parents: 85222
diff changeset
451 # mixed-in Enums should use the mixed-in type's __format__, otherwise
058cb219b3b5 Close #18738: Route __format__ calls to mixed-in type for mixed Enums (such as IntEnum).
Ethan Furman <ethan@stoneleaf.us>
parents: 85222
diff changeset
452 # we can get strange results with the Enum name showing up instead of
058cb219b3b5 Close #18738: Route __format__ calls to mixed-in type for mixed Enums (such as IntEnum).
Ethan Furman <ethan@stoneleaf.us>
parents: 85222
diff changeset
453 # the value
058cb219b3b5 Close #18738: Route __format__ calls to mixed-in type for mixed Enums (such as IntEnum).
Ethan Furman <ethan@stoneleaf.us>
parents: 85222
diff changeset
454
058cb219b3b5 Close #18738: Route __format__ calls to mixed-in type for mixed Enums (such as IntEnum).
Ethan Furman <ethan@stoneleaf.us>
parents: 85222
diff changeset
455 # pure Enum branch
058cb219b3b5 Close #18738: Route __format__ calls to mixed-in type for mixed Enums (such as IntEnum).
Ethan Furman <ethan@stoneleaf.us>
parents: 85222
diff changeset
456 if self._member_type_ is object:
058cb219b3b5 Close #18738: Route __format__ calls to mixed-in type for mixed Enums (such as IntEnum).
Ethan Furman <ethan@stoneleaf.us>
parents: 85222
diff changeset
457 cls = str
058cb219b3b5 Close #18738: Route __format__ calls to mixed-in type for mixed Enums (such as IntEnum).
Ethan Furman <ethan@stoneleaf.us>
parents: 85222
diff changeset
458 val = str(self)
058cb219b3b5 Close #18738: Route __format__ calls to mixed-in type for mixed Enums (such as IntEnum).
Ethan Furman <ethan@stoneleaf.us>
parents: 85222
diff changeset
459 # mix-in branch
058cb219b3b5 Close #18738: Route __format__ calls to mixed-in type for mixed Enums (such as IntEnum).
Ethan Furman <ethan@stoneleaf.us>
parents: 85222
diff changeset
460 else:
058cb219b3b5 Close #18738: Route __format__ calls to mixed-in type for mixed Enums (such as IntEnum).
Ethan Furman <ethan@stoneleaf.us>
parents: 85222
diff changeset
461 cls = self._member_type_
058cb219b3b5 Close #18738: Route __format__ calls to mixed-in type for mixed Enums (such as IntEnum).
Ethan Furman <ethan@stoneleaf.us>
parents: 85222
diff changeset
462 val = self.value
058cb219b3b5 Close #18738: Route __format__ calls to mixed-in type for mixed Enums (such as IntEnum).
Ethan Furman <ethan@stoneleaf.us>
parents: 85222
diff changeset
463 return cls.__format__(val, format_spec)
058cb219b3b5 Close #18738: Route __format__ calls to mixed-in type for mixed Enums (such as IntEnum).
Ethan Furman <ethan@stoneleaf.us>
parents: 85222
diff changeset
464
84130
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
465 def __getnewargs__(self):
84721
511c4daac102 Change _names to _names_ since the latter is reserved for Enum use.
Ethan Furman <ethan@stoneleaf.us>
parents: 84720
diff changeset
466 return (self._value_, )
84130
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
467
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
468 def __hash__(self):
84721
511c4daac102 Change _names to _names_ since the latter is reserved for Enum use.
Ethan Furman <ethan@stoneleaf.us>
parents: 84720
diff changeset
469 return hash(self._name_)
84130
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
470
85816
96081e7526f0 Issue19030: fixed comment that was still referring to a changed descriptor.
Ethan Furman <ethan@stoneleaf.us>
parents: 85796
diff changeset
471 # DynamicClassAttribute is used to provide access to the `name` and
96081e7526f0 Issue19030: fixed comment that was still referring to a changed descriptor.
Ethan Furman <ethan@stoneleaf.us>
parents: 85796
diff changeset
472 # `value` properties of enum members while keeping some measure of
84130
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
473 # protection from modification, while still allowing for an enumeration
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
474 # to have members named `name` and `value`. This works because enumeration
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
475 # members are not set directly on the enum class -- __getattr__ is
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
476 # used to look them up.
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
477
85796
436b606ecfe8 Close #19030: improvements to inspect and Enum.
Ethan Furman <ethan@stoneleaf.us>
parents: 85790
diff changeset
478 @DynamicClassAttribute
84130
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
479 def name(self):
85724
353ced6ae182 Close #18693: Enum is now more help() friendly.
Ethan Furman <ethan@stoneleaf.us>
parents: 85717
diff changeset
480 """The name of the Enum member."""
84721
511c4daac102 Change _names to _names_ since the latter is reserved for Enum use.
Ethan Furman <ethan@stoneleaf.us>
parents: 84720
diff changeset
481 return self._name_
84130
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
482
85796
436b606ecfe8 Close #19030: improvements to inspect and Enum.
Ethan Furman <ethan@stoneleaf.us>
parents: 85790
diff changeset
483 @DynamicClassAttribute
84130
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
484 def value(self):
85724
353ced6ae182 Close #18693: Enum is now more help() friendly.
Ethan Furman <ethan@stoneleaf.us>
parents: 85717
diff changeset
485 """The value of the Enum member."""
84721
511c4daac102 Change _names to _names_ since the latter is reserved for Enum use.
Ethan Furman <ethan@stoneleaf.us>
parents: 84720
diff changeset
486 return self._value_
84130
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
487
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
488
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
489 class IntEnum(int, Enum):
e7a01c7f69fe Closes issue 17947. Adds PEP-0435 (Adding an Enum type to the Python standard library).
Ethan Furman <ethan@stoneleaf.us>
parents:
diff changeset
490 """Enum where members are also (and must be) ints"""
84713
2079a517193b closes issue18042 -- a `unique` decorator is added to enum.py
Ethan Furman <ethan@stoneleaf.us>
parents: 84130
diff changeset
491
2079a517193b closes issue18042 -- a `unique` decorator is added to enum.py
Ethan Furman <ethan@stoneleaf.us>
parents: 84130
diff changeset
492
2079a517193b closes issue18042 -- a `unique` decorator is added to enum.py
Ethan Furman <ethan@stoneleaf.us>
parents: 84130
diff changeset
493 def unique(enumeration):
2079a517193b closes issue18042 -- a `unique` decorator is added to enum.py
Ethan Furman <ethan@stoneleaf.us>
parents: 84130
diff changeset
494 """Class decorator for enumerations ensuring unique member values."""
2079a517193b closes issue18042 -- a `unique` decorator is added to enum.py
Ethan Furman <ethan@stoneleaf.us>
parents: 84130
diff changeset
495 duplicates = []
2079a517193b closes issue18042 -- a `unique` decorator is added to enum.py
Ethan Furman <ethan@stoneleaf.us>
parents: 84130
diff changeset
496 for name, member in enumeration.__members__.items():
2079a517193b closes issue18042 -- a `unique` decorator is added to enum.py
Ethan Furman <ethan@stoneleaf.us>
parents: 84130
diff changeset
497 if name != member.name:
2079a517193b closes issue18042 -- a `unique` decorator is added to enum.py
Ethan Furman <ethan@stoneleaf.us>
parents: 84130
diff changeset
498 duplicates.append((name, member.name))
2079a517193b closes issue18042 -- a `unique` decorator is added to enum.py
Ethan Furman <ethan@stoneleaf.us>
parents: 84130
diff changeset
499 if duplicates:
2079a517193b closes issue18042 -- a `unique` decorator is added to enum.py
Ethan Furman <ethan@stoneleaf.us>
parents: 84130
diff changeset
500 alias_details = ', '.join(
2079a517193b closes issue18042 -- a `unique` decorator is added to enum.py
Ethan Furman <ethan@stoneleaf.us>
parents: 84130
diff changeset
501 ["%s -> %s" % (alias, name) for (alias, name) in duplicates])
2079a517193b closes issue18042 -- a `unique` decorator is added to enum.py
Ethan Furman <ethan@stoneleaf.us>
parents: 84130
diff changeset
502 raise ValueError('duplicate values found in %r: %s' %
2079a517193b closes issue18042 -- a `unique` decorator is added to enum.py
Ethan Furman <ethan@stoneleaf.us>
parents: 84130
diff changeset
503 (enumeration, alias_details))
2079a517193b closes issue18042 -- a `unique` decorator is added to enum.py
Ethan Furman <ethan@stoneleaf.us>
parents: 84130
diff changeset
504 return enumeration