summaryrefslogtreecommitdiff
path: root/Lib/enum.py
diff options
context:
space:
mode:
authorEthan Furman <ethan@stoneleaf.us>2021-10-20 20:55:46 -0700
committerGitHub <noreply@github.com>2021-10-20 20:55:46 -0700
commitc52338fc42353e8d0c6214e4c22427807439dfd5 (patch)
tree6da4bf5da5eb739aa48eab1850218d5726c45b10 /Lib/enum.py
parent8f05ffb0534c2343fc45ad0e1d91ae1dc2d92b64 (diff)
parent2a9ab75af32b1ee9f210ae2a0718990687d0f79d (diff)
downloadcpython-git-enum-private-310.tar.gz
Merge branch '3.10' into enum-private-310enum-private-310
Diffstat (limited to 'Lib/enum.py')
-rw-r--r--Lib/enum.py60
1 files changed, 37 insertions, 23 deletions
diff --git a/Lib/enum.py b/Lib/enum.py
index db79e66903..f5657a6eba 100644
--- a/Lib/enum.py
+++ b/Lib/enum.py
@@ -44,10 +44,11 @@ def _is_sunder(name):
def _is_private(cls_name, name):
# do not use `re` as `re` imports `enum`
pattern = '_%s__' % (cls_name, )
+ pat_len = len(pattern)
if (
- len(name) >= 5
+ len(name) > pat_len
and name.startswith(pattern)
- and name[len(pattern)] != '_'
+ and name[pat_len:pat_len+1] != ['_']
and (name[-1] != '_' or name[-2] != '_')
):
return True
@@ -392,12 +393,19 @@ class EnumMeta(type):
start=start,
)
- def __contains__(cls, member):
- if not isinstance(member, Enum):
+ def __contains__(cls, obj):
+ if not isinstance(obj, Enum):
+ import warnings
+ warnings.warn(
+ "in 3.12 __contains__ will no longer raise TypeError, but will return True if\n"
+ "obj is a member or a member's value",
+ DeprecationWarning,
+ stacklevel=2,
+ )
raise TypeError(
"unsupported operand type(s) for 'in': '%s' and '%s'" % (
- type(member).__qualname__, cls.__class__.__qualname__))
- return isinstance(member, cls) and member._name_ in cls._member_map_
+ type(obj).__qualname__, cls.__class__.__qualname__))
+ return isinstance(obj, cls) and obj._name_ in cls._member_map_
def __delattr__(cls, attr):
# nicer error message when someone tries to delete an attribute
@@ -580,7 +588,7 @@ class EnumMeta(type):
return object, Enum
def _find_data_type(bases):
- data_types = []
+ data_types = set()
for chain in bases:
candidate = None
for base in chain.__mro__:
@@ -588,19 +596,19 @@ class EnumMeta(type):
continue
elif issubclass(base, Enum):
if base._member_type_ is not object:
- data_types.append(base._member_type_)
+ data_types.add(base._member_type_)
break
elif '__new__' in base.__dict__:
if issubclass(base, Enum):
continue
- data_types.append(candidate or base)
+ data_types.add(candidate or base)
break
else:
candidate = candidate or base
if len(data_types) > 1:
raise TypeError('%r: too many data types: %r' % (class_name, data_types))
elif data_types:
- return data_types[0]
+ return data_types.pop()
else:
return None
@@ -693,19 +701,25 @@ class Enum(metaclass=EnumMeta):
except Exception as e:
exc = e
result = None
- if isinstance(result, cls):
- return result
- else:
- ve_exc = ValueError("%r is not a valid %s" % (value, cls.__qualname__))
- if result is None and exc is None:
- raise ve_exc
- elif exc is None:
- exc = TypeError(
- 'error in %s._missing_: returned %r instead of None or a valid member'
- % (cls.__name__, result)
- )
- exc.__context__ = ve_exc
- raise exc
+ try:
+ if isinstance(result, cls):
+ return result
+ else:
+ ve_exc = ValueError("%r is not a valid %s" % (value, cls.__qualname__))
+ if result is None and exc is None:
+ raise ve_exc
+ elif exc is None:
+ exc = TypeError(
+ 'error in %s._missing_: returned %r instead of None or a valid member'
+ % (cls.__name__, result)
+ )
+ if not isinstance(exc, ValueError):
+ exc.__context__ = ve_exc
+ raise exc
+ finally:
+ # ensure all variables that could hold an exception are destroyed
+ exc = None
+ ve_exc = None
def _generate_next_value_(name, start, count, last_values):
"""