mirror of
https://github.com/python/cpython.git
synced 2025-09-27 10:50:04 +00:00
bpo-42248: [Enum] ensure exceptions raised in `_missing_
` are released (GH-25350)
This commit is contained in:
parent
67c0b3d89c
commit
8c14f5a787
3 changed files with 57 additions and 19 deletions
|
@ -919,6 +919,7 @@ class Enum(metaclass=EnumType):
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
exc = e
|
exc = e
|
||||||
result = None
|
result = None
|
||||||
|
try:
|
||||||
if isinstance(result, cls):
|
if isinstance(result, cls):
|
||||||
return result
|
return result
|
||||||
elif (
|
elif (
|
||||||
|
@ -938,6 +939,10 @@ class Enum(metaclass=EnumType):
|
||||||
if not isinstance(exc, ValueError):
|
if not isinstance(exc, ValueError):
|
||||||
exc.__context__ = ve_exc
|
exc.__context__ = ve_exc
|
||||||
raise 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):
|
def _generate_next_value_(name, start, count, last_values):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -1932,6 +1932,38 @@ class TestEnum(unittest.TestCase):
|
||||||
else:
|
else:
|
||||||
raise Exception('Exception not raised.')
|
raise Exception('Exception not raised.')
|
||||||
|
|
||||||
|
def test_missing_exceptions_reset(self):
|
||||||
|
import weakref
|
||||||
|
#
|
||||||
|
class TestEnum(enum.Enum):
|
||||||
|
VAL1 = 'val1'
|
||||||
|
VAL2 = 'val2'
|
||||||
|
#
|
||||||
|
class Class1:
|
||||||
|
def __init__(self):
|
||||||
|
# Gracefully handle an exception of our own making
|
||||||
|
try:
|
||||||
|
raise ValueError()
|
||||||
|
except ValueError:
|
||||||
|
pass
|
||||||
|
#
|
||||||
|
class Class2:
|
||||||
|
def __init__(self):
|
||||||
|
# Gracefully handle an exception of Enum's making
|
||||||
|
try:
|
||||||
|
TestEnum('invalid_value')
|
||||||
|
except ValueError:
|
||||||
|
pass
|
||||||
|
# No strong refs here so these are free to die.
|
||||||
|
class_1_ref = weakref.ref(Class1())
|
||||||
|
class_2_ref = weakref.ref(Class2())
|
||||||
|
#
|
||||||
|
# The exception raised by Enum creates a reference loop and thus
|
||||||
|
# Class2 instances will stick around until the next gargage collection
|
||||||
|
# cycle, unlike Class1.
|
||||||
|
self.assertIs(class_1_ref(), None)
|
||||||
|
self.assertIs(class_2_ref(), None)
|
||||||
|
|
||||||
def test_multiple_mixin(self):
|
def test_multiple_mixin(self):
|
||||||
class MaxMixin:
|
class MaxMixin:
|
||||||
@classproperty
|
@classproperty
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
[Enum] ensure exceptions raised in ``_missing__`` are released
|
Loading…
Add table
Add a link
Reference in a new issue