mirror of
https://github.com/python/cpython.git
synced 2025-12-08 06:10:17 +00:00
bpo-44559: [Enum] restore fixes lost in 3.9 reversion (GH-29114)
- fix exception leaks - re-add deprecation warnings
This commit is contained in:
parent
64e83c711e
commit
2a9ab75af3
3 changed files with 194 additions and 42 deletions
|
|
@ -11,6 +11,7 @@
|
|||
from test.support import ALWAYS_EQ, check__all__, threading_helper
|
||||
from datetime import timedelta
|
||||
|
||||
python_version = sys.version_info[:2]
|
||||
|
||||
# for pickle tests
|
||||
try:
|
||||
|
|
@ -347,17 +348,38 @@ class IntLogic(int, Enum):
|
|||
self.assertTrue(IntLogic.true)
|
||||
self.assertFalse(IntLogic.false)
|
||||
|
||||
def test_contains(self):
|
||||
@unittest.skipIf(
|
||||
python_version >= (3, 12),
|
||||
'__contains__ now returns True/False for all inputs',
|
||||
)
|
||||
def test_contains_er(self):
|
||||
Season = self.Season
|
||||
self.assertIn(Season.AUTUMN, Season)
|
||||
with self.assertRaises(TypeError):
|
||||
3 in Season
|
||||
with self.assertWarns(DeprecationWarning):
|
||||
3 in Season
|
||||
with self.assertRaises(TypeError):
|
||||
'AUTUMN' in Season
|
||||
|
||||
with self.assertWarns(DeprecationWarning):
|
||||
'AUTUMN' in Season
|
||||
val = Season(3)
|
||||
self.assertIn(val, Season)
|
||||
#
|
||||
class OtherEnum(Enum):
|
||||
one = 1; two = 2
|
||||
self.assertNotIn(OtherEnum.two, Season)
|
||||
|
||||
@unittest.skipIf(
|
||||
python_version < (3, 12),
|
||||
'__contains__ only works with enum memmbers before 3.12',
|
||||
)
|
||||
def test_contains_tf(self):
|
||||
Season = self.Season
|
||||
self.assertIn(Season.AUTUMN, Season)
|
||||
self.assertTrue(3 in Season)
|
||||
self.assertFalse('AUTUMN' in Season)
|
||||
val = Season(3)
|
||||
self.assertIn(val, Season)
|
||||
#
|
||||
class OtherEnum(Enum):
|
||||
one = 1; two = 2
|
||||
self.assertNotIn(OtherEnum.two, Season)
|
||||
|
|
@ -1932,6 +1954,38 @@ def _missing_(cls, item):
|
|||
else:
|
||||
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):
|
||||
class MaxMixin:
|
||||
@classproperty
|
||||
|
|
@ -2085,7 +2139,7 @@ def test_empty_globals(self):
|
|||
exec(code, global_ns, local_ls)
|
||||
|
||||
@unittest.skipUnless(
|
||||
sys.version_info[:2] == (3, 9),
|
||||
python_version == (3, 9),
|
||||
'private variables are now normal attributes',
|
||||
)
|
||||
def test_warning_for_private_variables(self):
|
||||
|
|
@ -2390,19 +2444,42 @@ def test_pickle(self):
|
|||
test_pickle_dump_load(self.assertIs, FlagStooges.CURLY|FlagStooges.MOE)
|
||||
test_pickle_dump_load(self.assertIs, FlagStooges)
|
||||
|
||||
def test_contains(self):
|
||||
@unittest.skipIf(
|
||||
python_version >= (3, 12),
|
||||
'__contains__ now returns True/False for all inputs',
|
||||
)
|
||||
def test_contains_er(self):
|
||||
Open = self.Open
|
||||
Color = self.Color
|
||||
self.assertFalse(Color.BLACK in Open)
|
||||
self.assertFalse(Open.RO in Color)
|
||||
with self.assertRaises(TypeError):
|
||||
'BLACK' in Color
|
||||
with self.assertWarns(DeprecationWarning):
|
||||
'BLACK' in Color
|
||||
with self.assertRaises(TypeError):
|
||||
'RO' in Open
|
||||
with self.assertWarns(DeprecationWarning):
|
||||
'RO' in Open
|
||||
with self.assertRaises(TypeError):
|
||||
1 in Color
|
||||
with self.assertWarns(DeprecationWarning):
|
||||
1 in Color
|
||||
with self.assertRaises(TypeError):
|
||||
1 in Open
|
||||
with self.assertWarns(DeprecationWarning):
|
||||
1 in Open
|
||||
|
||||
@unittest.skipIf(
|
||||
python_version < (3, 12),
|
||||
'__contains__ only works with enum memmbers before 3.12',
|
||||
)
|
||||
def test_contains_tf(self):
|
||||
Open = self.Open
|
||||
Color = self.Color
|
||||
self.assertFalse(Color.BLACK in Open)
|
||||
self.assertFalse(Open.RO in Color)
|
||||
self.assertFalse('BLACK' in Color)
|
||||
self.assertFalse('RO' in Open)
|
||||
self.assertTrue(1 in Color)
|
||||
self.assertTrue(1 in Open)
|
||||
|
||||
|
||||
def test_member_contains(self):
|
||||
Perm = self.Perm
|
||||
|
|
@ -2883,7 +2960,11 @@ def test_programatic_function_from_empty_tuple(self):
|
|||
self.assertEqual(len(lst), len(Thing))
|
||||
self.assertEqual(len(Thing), 0, Thing)
|
||||
|
||||
def test_contains(self):
|
||||
@unittest.skipIf(
|
||||
python_version >= (3, 12),
|
||||
'__contains__ now returns True/False for all inputs',
|
||||
)
|
||||
def test_contains_er(self):
|
||||
Open = self.Open
|
||||
Color = self.Color
|
||||
self.assertTrue(Color.GREEN in Color)
|
||||
|
|
@ -2891,13 +2972,33 @@ def test_contains(self):
|
|||
self.assertFalse(Color.GREEN in Open)
|
||||
self.assertFalse(Open.RW in Color)
|
||||
with self.assertRaises(TypeError):
|
||||
'GREEN' in Color
|
||||
with self.assertWarns(DeprecationWarning):
|
||||
'GREEN' in Color
|
||||
with self.assertRaises(TypeError):
|
||||
'RW' in Open
|
||||
with self.assertWarns(DeprecationWarning):
|
||||
'RW' in Open
|
||||
with self.assertRaises(TypeError):
|
||||
2 in Color
|
||||
with self.assertWarns(DeprecationWarning):
|
||||
2 in Color
|
||||
with self.assertRaises(TypeError):
|
||||
2 in Open
|
||||
with self.assertWarns(DeprecationWarning):
|
||||
2 in Open
|
||||
|
||||
@unittest.skipIf(
|
||||
python_version < (3, 12),
|
||||
'__contains__ only works with enum memmbers before 3.12',
|
||||
)
|
||||
def test_contains_tf(self):
|
||||
Open = self.Open
|
||||
Color = self.Color
|
||||
self.assertTrue(Color.GREEN in Color)
|
||||
self.assertTrue(Open.RW in Open)
|
||||
self.assertTrue(Color.GREEN in Open)
|
||||
self.assertTrue(Open.RW in Color)
|
||||
self.assertFalse('GREEN' in Color)
|
||||
self.assertFalse('RW' in Open)
|
||||
self.assertTrue(2 in Color)
|
||||
self.assertTrue(2 in Open)
|
||||
|
||||
def test_member_contains(self):
|
||||
Perm = self.Perm
|
||||
|
|
@ -3267,7 +3368,7 @@ def test_convert(self):
|
|||
if name[0:2] not in ('CO', '__')],
|
||||
[], msg='Names other than CONVERT_TEST_* found.')
|
||||
|
||||
@unittest.skipUnless(sys.version_info[:2] == (3, 8),
|
||||
@unittest.skipUnless(python_version == (3, 8),
|
||||
'_convert was deprecated in 3.8')
|
||||
def test_convert_warn(self):
|
||||
with self.assertWarns(DeprecationWarning):
|
||||
|
|
@ -3276,7 +3377,7 @@ def test_convert_warn(self):
|
|||
('test.test_enum', '__main__')[__name__=='__main__'],
|
||||
filter=lambda x: x.startswith('CONVERT_TEST_'))
|
||||
|
||||
@unittest.skipUnless(sys.version_info >= (3, 9),
|
||||
@unittest.skipUnless(python_version >= (3, 9),
|
||||
'_convert was removed in 3.9')
|
||||
def test_convert_raise(self):
|
||||
with self.assertRaises(AttributeError):
|
||||
|
|
@ -3285,6 +3386,33 @@ def test_convert_raise(self):
|
|||
('test.test_enum', '__main__')[__name__=='__main__'],
|
||||
filter=lambda x: x.startswith('CONVERT_TEST_'))
|
||||
|
||||
class TestHelpers(unittest.TestCase):
|
||||
|
||||
sunder_names = '_bad_', '_good_', '_what_ho_'
|
||||
dunder_names = '__mal__', '__bien__', '__que_que__'
|
||||
private_names = '_MyEnum__private', '_MyEnum__still_private'
|
||||
private_and_sunder_names = '_MyEnum__private_', '_MyEnum__also_private_'
|
||||
random_names = 'okay', '_semi_private', '_weird__', '_MyEnum__'
|
||||
|
||||
def test_sunder(self):
|
||||
for name in self.sunder_names + self.private_and_sunder_names:
|
||||
self.assertTrue(enum._is_sunder(name), '%r is a not sunder name?' % name)
|
||||
for name in self.dunder_names + self.private_names + self.random_names:
|
||||
self.assertFalse(enum._is_sunder(name), '%r is a sunder name?' % name)
|
||||
|
||||
def test_dunder(self):
|
||||
for name in self.dunder_names:
|
||||
self.assertTrue(enum._is_dunder(name), '%r is a not dunder name?' % name)
|
||||
for name in self.sunder_names + self.private_names + self.private_and_sunder_names + self.random_names:
|
||||
self.assertFalse(enum._is_dunder(name), '%r is a dunder name?' % name)
|
||||
|
||||
def test_is_private(self):
|
||||
for name in self.private_names + self.private_and_sunder_names:
|
||||
self.assertTrue(enum._is_private('MyEnum', name), '%r is a not private name?')
|
||||
for name in self.sunder_names + self.dunder_names + self.random_names:
|
||||
self.assertFalse(enum._is_private('MyEnum', name), '%r is a private name?')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue