annotate Lib/enum.py @ 87488:124e51c19e4f

Issue #19734: Also run pip version check in isolated mode
author Nick Coghlan <ncoghlan@gmail.com>
date Sun, 24 Nov 2013 16:49:20 +1000
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