Skip to content

Commit 5e0eace

Browse files
committed
test_exception_group from CPython 3.12.2
1 parent e7fdfca commit 5e0eace

File tree

1 file changed

+32
-60
lines changed

1 file changed

+32
-60
lines changed

Lib/test/test_exception_group.py

+32-60
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,9 @@
11
import collections.abc
2-
import traceback
32
import types
43
import unittest
5-
4+
from test.support import C_RECURSION_LIMIT
65

76
class TestExceptionGroupTypeHierarchy(unittest.TestCase):
8-
# TODO: RUSTPYTHON
9-
@unittest.expectedFailure
107
def test_exception_group_types(self):
118
self.assertTrue(issubclass(ExceptionGroup, Exception))
129
self.assertTrue(issubclass(ExceptionGroup, BaseExceptionGroup))
@@ -38,17 +35,13 @@ def test_bad_EG_construction__too_many_args(self):
3835
with self.assertRaisesRegex(TypeError, MSG):
3936
ExceptionGroup('eg', [ValueError('too')], [TypeError('many')])
4037

41-
# TODO: RUSTPYTHON
42-
@unittest.expectedFailure
4338
def test_bad_EG_construction__bad_message(self):
4439
MSG = 'argument 1 must be str, not '
4540
with self.assertRaisesRegex(TypeError, MSG):
4641
ExceptionGroup(ValueError(12), SyntaxError('bad syntax'))
4742
with self.assertRaisesRegex(TypeError, MSG):
4843
ExceptionGroup(None, [ValueError(12)])
4944

50-
# TODO: RUSTPYTHON
51-
@unittest.expectedFailure
5245
def test_bad_EG_construction__bad_excs_sequence(self):
5346
MSG = r'second argument \(exceptions\) must be a sequence'
5447
with self.assertRaisesRegex(TypeError, MSG):
@@ -60,8 +53,6 @@ def test_bad_EG_construction__bad_excs_sequence(self):
6053
with self.assertRaisesRegex(ValueError, MSG):
6154
ExceptionGroup("eg", [])
6255

63-
# TODO: RUSTPYTHON
64-
@unittest.expectedFailure
6556
def test_bad_EG_construction__nested_non_exceptions(self):
6657
MSG = (r'Item [0-9]+ of second argument \(exceptions\)'
6758
' is not an exception')
@@ -78,16 +69,12 @@ def test_EG_wraps_Exceptions__creates_EG(self):
7869
type(ExceptionGroup("eg", excs)),
7970
ExceptionGroup)
8071

81-
# TODO: RUSTPYTHON
82-
@unittest.expectedFailure
8372
def test_BEG_wraps_Exceptions__creates_EG(self):
8473
excs = [ValueError(1), TypeError(2)]
8574
self.assertIs(
8675
type(BaseExceptionGroup("beg", excs)),
8776
ExceptionGroup)
8877

89-
# TODO: RUSTPYTHON
90-
@unittest.expectedFailure
9178
def test_EG_wraps_BaseException__raises_TypeError(self):
9279
MSG= "Cannot nest BaseExceptions in an ExceptionGroup"
9380
with self.assertRaisesRegex(TypeError, MSG):
@@ -105,8 +92,6 @@ class MyEG(ExceptionGroup):
10592
type(MyEG("eg", [ValueError(12), TypeError(42)])),
10693
MyEG)
10794

108-
# TODO: RUSTPYTHON
109-
@unittest.expectedFailure
11095
def test_EG_subclass_does_not_wrap_base_exceptions(self):
11196
class MyEG(ExceptionGroup):
11297
pass
@@ -115,8 +100,6 @@ class MyEG(ExceptionGroup):
115100
with self.assertRaisesRegex(TypeError, msg):
116101
MyEG("eg", [ValueError(12), KeyboardInterrupt(42)])
117102

118-
# TODO: RUSTPYTHON
119-
@unittest.expectedFailure
120103
def test_BEG_and_E_subclass_does_not_wrap_base_exceptions(self):
121104
class MyEG(BaseExceptionGroup, ValueError):
122105
pass
@@ -125,6 +108,21 @@ class MyEG(BaseExceptionGroup, ValueError):
125108
with self.assertRaisesRegex(TypeError, msg):
126109
MyEG("eg", [ValueError(12), KeyboardInterrupt(42)])
127110

111+
def test_EG_and_specific_subclass_can_wrap_any_nonbase_exception(self):
112+
class MyEG(ExceptionGroup, ValueError):
113+
pass
114+
115+
# The restriction is specific to Exception, not "the other base class"
116+
MyEG("eg", [ValueError(12), Exception()])
117+
118+
def test_BEG_and_specific_subclass_can_wrap_any_nonbase_exception(self):
119+
class MyEG(BaseExceptionGroup, ValueError):
120+
pass
121+
122+
# The restriction is specific to Exception, not "the other base class"
123+
MyEG("eg", [ValueError(12), Exception()])
124+
125+
128126
def test_BEG_subclass_wraps_anything(self):
129127
class MyBEG(BaseExceptionGroup):
130128
pass
@@ -138,8 +136,6 @@ class MyBEG(BaseExceptionGroup):
138136

139137

140138
class StrAndReprTests(unittest.TestCase):
141-
# TODO: RUSTPYTHON
142-
@unittest.expectedFailure
143139
def test_ExceptionGroup(self):
144140
eg = BaseExceptionGroup(
145141
'flat', [ValueError(1), TypeError(2)])
@@ -160,8 +156,6 @@ def test_ExceptionGroup(self):
160156
"ExceptionGroup('flat', "
161157
"[ValueError(1), TypeError(2)]), TypeError(2)])")
162158

163-
# TODO: RUSTPYTHON
164-
@unittest.expectedFailure
165159
def test_BaseExceptionGroup(self):
166160
eg = BaseExceptionGroup(
167161
'flat', [ValueError(1), KeyboardInterrupt(2)])
@@ -184,8 +178,6 @@ def test_BaseExceptionGroup(self):
184178
"BaseExceptionGroup('flat', "
185179
"[ValueError(1), KeyboardInterrupt(2)])])")
186180

187-
# TODO: RUSTPYTHON
188-
@unittest.expectedFailure
189181
def test_custom_exception(self):
190182
class MyEG(ExceptionGroup):
191183
pass
@@ -270,8 +262,6 @@ def test_basics_ExceptionGroup_fields(self):
270262
self.assertIsNone(tb.tb_next)
271263
self.assertEqual(tb.tb_lineno, tb_linenos[1][i])
272264

273-
# TODO: RUSTPYTHON
274-
@unittest.expectedFailure
275265
def test_fields_are_readonly(self):
276266
eg = ExceptionGroup('eg', [TypeError(1), OSError(2)])
277267

@@ -287,8 +277,6 @@ def test_fields_are_readonly(self):
287277

288278

289279
class ExceptionGroupTestBase(unittest.TestCase):
290-
# TODO: RUSTPYTHON
291-
@unittest.expectedFailure
292280
def assertMatchesTemplate(self, exc, exc_type, template):
293281
""" Assert that the exception matches the template
294282
@@ -318,7 +306,6 @@ def setUp(self):
318306
self.eg = create_simple_eg()
319307
self.eg_template = [ValueError(1), TypeError(int), ValueError(2)]
320308

321-
@unittest.skip("TODO: RUSTPYTHON")
322309
def test_basics_subgroup_split__bad_arg_type(self):
323310
bad_args = ["bad arg",
324311
OSError('instance not type'),
@@ -330,20 +317,16 @@ def test_basics_subgroup_split__bad_arg_type(self):
330317
with self.assertRaises(TypeError):
331318
self.eg.split(arg)
332319

333-
334-
@unittest.skip("TODO: RUSTPYTHON")
335320
def test_basics_subgroup_by_type__passthrough(self):
336321
eg = self.eg
337322
self.assertIs(eg, eg.subgroup(BaseException))
338323
self.assertIs(eg, eg.subgroup(Exception))
339324
self.assertIs(eg, eg.subgroup(BaseExceptionGroup))
340325
self.assertIs(eg, eg.subgroup(ExceptionGroup))
341326

342-
@unittest.skip("TODO: RUSTPYTHON")
343327
def test_basics_subgroup_by_type__no_match(self):
344328
self.assertIsNone(self.eg.subgroup(OSError))
345329

346-
@unittest.skip("TODO: RUSTPYTHON")
347330
def test_basics_subgroup_by_type__match(self):
348331
eg = self.eg
349332
testcases = [
@@ -358,15 +341,12 @@ def test_basics_subgroup_by_type__match(self):
358341
self.assertEqual(subeg.message, eg.message)
359342
self.assertMatchesTemplate(subeg, ExceptionGroup, template)
360343

361-
@unittest.skip("TODO: RUSTPYTHON")
362344
def test_basics_subgroup_by_predicate__passthrough(self):
363345
self.assertIs(self.eg, self.eg.subgroup(lambda e: True))
364346

365-
@unittest.skip("TODO: RUSTPYTHON")
366347
def test_basics_subgroup_by_predicate__no_match(self):
367348
self.assertIsNone(self.eg.subgroup(lambda e: False))
368349

369-
@unittest.skip("TODO: RUSTPYTHON")
370350
def test_basics_subgroup_by_predicate__match(self):
371351
eg = self.eg
372352
testcases = [
@@ -386,7 +366,6 @@ def setUp(self):
386366
self.eg = create_simple_eg()
387367
self.eg_template = [ValueError(1), TypeError(int), ValueError(2)]
388368

389-
@unittest.skip("TODO: RUSTPYTHON")
390369
def test_basics_split_by_type__passthrough(self):
391370
for E in [BaseException, Exception,
392371
BaseExceptionGroup, ExceptionGroup]:
@@ -395,14 +374,12 @@ def test_basics_split_by_type__passthrough(self):
395374
match, ExceptionGroup, self.eg_template)
396375
self.assertIsNone(rest)
397376

398-
@unittest.skip("TODO: RUSTPYTHON")
399377
def test_basics_split_by_type__no_match(self):
400378
match, rest = self.eg.split(OSError)
401379
self.assertIsNone(match)
402380
self.assertMatchesTemplate(
403381
rest, ExceptionGroup, self.eg_template)
404382

405-
@unittest.skip("TODO: RUSTPYTHON")
406383
def test_basics_split_by_type__match(self):
407384
eg = self.eg
408385
VE = ValueError
@@ -427,19 +404,16 @@ def test_basics_split_by_type__match(self):
427404
else:
428405
self.assertIsNone(rest)
429406

430-
@unittest.skip("TODO: RUSTPYTHON")
431407
def test_basics_split_by_predicate__passthrough(self):
432408
match, rest = self.eg.split(lambda e: True)
433409
self.assertMatchesTemplate(match, ExceptionGroup, self.eg_template)
434410
self.assertIsNone(rest)
435411

436-
@unittest.skip("TODO: RUSTPYTHON")
437412
def test_basics_split_by_predicate__no_match(self):
438413
match, rest = self.eg.split(lambda e: False)
439414
self.assertIsNone(match)
440415
self.assertMatchesTemplate(rest, ExceptionGroup, self.eg_template)
441416

442-
@unittest.skip("TODO: RUSTPYTHON")
443417
def test_basics_split_by_predicate__match(self):
444418
eg = self.eg
445419
VE = ValueError
@@ -465,19 +439,15 @@ def test_basics_split_by_predicate__match(self):
465439
class DeepRecursionInSplitAndSubgroup(unittest.TestCase):
466440
def make_deep_eg(self):
467441
e = TypeError(1)
468-
for i in range(2000):
442+
for i in range(C_RECURSION_LIMIT + 1):
469443
e = ExceptionGroup('eg', [e])
470444
return e
471445

472-
# TODO: RUSTPYTHON
473-
@unittest.expectedFailure
474446
def test_deep_split(self):
475447
e = self.make_deep_eg()
476448
with self.assertRaises(RecursionError):
477449
e.split(TypeError)
478450

479-
# TODO: RUSTPYTHON
480-
@unittest.expectedFailure
481451
def test_deep_subgroup(self):
482452
e = self.make_deep_eg()
483453
with self.assertRaises(RecursionError):
@@ -501,7 +471,7 @@ def leaf_generator(exc, tbs=None):
501471

502472
class LeafGeneratorTest(unittest.TestCase):
503473
# The leaf_generator is mentioned in PEP 654 as a suggestion
504-
# on how to iterate over leaf nodes of an EG. It is also
474+
# on how to iterate over leaf nodes of an EG. Is is also
505475
# used below as a test utility. So we test it here.
506476

507477
def test_leaf_generator(self):
@@ -654,8 +624,6 @@ def tb_linenos(tbs):
654624

655625
class NestedExceptionGroupSplitTest(ExceptionGroupSplitTestBase):
656626

657-
# TODO: RUSTPYTHON
658-
@unittest.expectedFailure
659627
def test_split_by_type(self):
660628
class MyExceptionGroup(ExceptionGroup):
661629
pass
@@ -755,8 +723,6 @@ def level3(i):
755723
self.assertMatchesTemplate(match, ExceptionGroup, [eg_template[0]])
756724
self.assertMatchesTemplate(rest, ExceptionGroup, [eg_template[1]])
757725

758-
# TODO: RUSTPYTHON
759-
@unittest.expectedFailure
760726
def test_split_BaseExceptionGroup(self):
761727
def exc(ex):
762728
try:
@@ -797,8 +763,6 @@ def exc(ex):
797763
self.assertMatchesTemplate(
798764
rest, ExceptionGroup, [ValueError(1)])
799765

800-
# TODO: RUSTPYTHON
801-
@unittest.expectedFailure
802766
def test_split_copies_notes(self):
803767
# make sure each exception group after a split has its own __notes__ list
804768
eg = ExceptionGroup("eg", [ValueError(1), TypeError(2)])
@@ -830,11 +794,23 @@ def test_split_does_not_copy_non_sequence_notes(self):
830794
self.assertFalse(hasattr(match, '__notes__'))
831795
self.assertFalse(hasattr(rest, '__notes__'))
832796

797+
# TODO: RUSTPYTHON
798+
@unittest.expectedFailure
799+
def test_drive_invalid_return_value(self):
800+
class MyEg(ExceptionGroup):
801+
def derive(self, excs):
802+
return 42
803+
804+
eg = MyEg('eg', [TypeError(1), ValueError(2)])
805+
msg = "derive must return an instance of BaseExceptionGroup"
806+
with self.assertRaisesRegex(TypeError, msg):
807+
eg.split(TypeError)
808+
with self.assertRaisesRegex(TypeError, msg):
809+
eg.subgroup(TypeError)
810+
833811

834812
class NestedExceptionGroupSubclassSplitTest(ExceptionGroupSplitTestBase):
835813

836-
# TODO: RUSTPYTHON
837-
@unittest.expectedFailure
838814
def test_split_ExceptionGroup_subclass_no_derive_no_new_override(self):
839815
class EG(ExceptionGroup):
840816
pass
@@ -877,8 +853,6 @@ class EG(ExceptionGroup):
877853
self.assertMatchesTemplate(match, ExceptionGroup, [[TypeError(2)]])
878854
self.assertMatchesTemplate(rest, ExceptionGroup, [ValueError(1)])
879855

880-
# TODO: RUSTPYTHON
881-
@unittest.expectedFailure
882856
def test_split_BaseExceptionGroup_subclass_no_derive_new_override(self):
883857
class EG(BaseExceptionGroup):
884858
def __new__(cls, message, excs, unused):
@@ -921,8 +895,6 @@ def __new__(cls, message, excs, unused):
921895
match, BaseExceptionGroup, [KeyboardInterrupt(2)])
922896
self.assertMatchesTemplate(rest, ExceptionGroup, [ValueError(1)])
923897

924-
# TODO: RUSTPYTHON
925-
@unittest.expectedFailure
926898
def test_split_ExceptionGroup_subclass_derive_and_new_overrides(self):
927899
class EG(ExceptionGroup):
928900
def __new__(cls, message, excs, code):

0 commit comments

Comments
 (0)