aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/Lib/enum.py
diff options
context:
space:
mode:
authorEthan Furman <ethan@stoneleaf.us>2021-04-27 13:05:08 -0700
committerGitHub <noreply@github.com>2021-04-27 13:05:08 -0700
commit6bd9288b805c765ec2433f66aa4d82e05767325f (patch)
tree5810c0de5a0086fec858ccf222cf1d42d459ba96 /Lib/enum.py
parent9aea31deddf7458be3546f72185740f3cd06687f (diff)
downloadcpython-6bd9288b805c765ec2433f66aa4d82e05767325f.tar.gz
cpython-6bd9288b805c765ec2433f66aa4d82e05767325f.zip
bpo-43957: [Enum] Deprecate ``TypeError`` from containment checks. (GH-25670)
In 3.12 ``True`` or ``False`` will be returned for all containment checks, with ``True`` being returned if the value is either a member of that enum or one of its members' value.
Diffstat (limited to 'Lib/enum.py')
-rw-r--r--Lib/enum.py29
1 files changed, 20 insertions, 9 deletions
diff --git a/Lib/enum.py b/Lib/enum.py
index bcf411c6b65..bccf024b520 100644
--- a/Lib/enum.py
+++ b/Lib/enum.py
@@ -280,7 +280,8 @@ class _proto_member:
# linear.
enum_class._value2member_map_.setdefault(value, enum_member)
except TypeError:
- pass
+ # keep track of the value in a list so containment checks are quick
+ enum_class._unhashable_values_.append(value)
class _EnumDict(dict):
@@ -440,6 +441,7 @@ class EnumType(type):
classdict['_member_names_'] = []
classdict['_member_map_'] = {}
classdict['_value2member_map_'] = {}
+ classdict['_unhashable_values_'] = []
classdict['_member_type_'] = member_type
#
# Flag structures (will be removed if final class is not a Flag
@@ -622,6 +624,13 @@ class EnumType(type):
def __contains__(cls, member):
if not isinstance(member, Enum):
+ import warnings
+ warnings.warn(
+ "in 3.12 __contains__ will no longer raise TypeError, but will return True or\n"
+ "False depending on whether the value is a member or the value of a member",
+ DeprecationWarning,
+ stacklevel=2,
+ )
raise TypeError(
"unsupported operand type(s) for 'in': '%s' and '%s'" % (
type(member).__qualname__, cls.__class__.__qualname__))
@@ -1005,14 +1014,15 @@ class Enum(metaclass=EnumType):
val = str(self)
# mix-in branch
else:
- import warnings
- warnings.warn(
- "in 3.12 format() will use the enum member, not the enum member's value;\n"
- "use a format specifier, such as :d for an IntEnum member, to maintain"
- "the current display",
- DeprecationWarning,
- stacklevel=2,
- )
+ if not format_spec or format_spec in ('{}','{:}'):
+ import warnings
+ warnings.warn(
+ "in 3.12 format() will use the enum member, not the enum member's value;\n"
+ "use a format specifier, such as :d for an IntEnum member, to maintain"
+ "the current display",
+ DeprecationWarning,
+ stacklevel=2,
+ )
cls = self._member_type_
val = self._value_
return cls.__format__(val, format_spec)
@@ -1434,6 +1444,7 @@ def _simple_enum(etype=Enum, *, boundary=None, use_args=None):
body['_member_names_'] = member_names = []
body['_member_map_'] = member_map = {}
body['_value2member_map_'] = value2member_map = {}
+ body['_unhashable_values_'] = []
body['_member_type_'] = member_type = etype._member_type_
if issubclass(etype, Flag):
body['_boundary_'] = boundary or etype._boundary_