python (3.12.0)
1 import sys
2 import unittest
3 import textwrap
4 from test.support.testcase import ExceptionIsLikeMixin
5
6 class ESC[4;38;5;81mTestInvalidExceptStar(ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
7 def test_mixed_except_and_except_star_is_syntax_error(self):
8 errors = [
9 "try: pass\nexcept ValueError: pass\nexcept* TypeError: pass\n",
10 "try: pass\nexcept* ValueError: pass\nexcept TypeError: pass\n",
11 "try: pass\nexcept ValueError as e: pass\nexcept* TypeError: pass\n",
12 "try: pass\nexcept* ValueError as e: pass\nexcept TypeError: pass\n",
13 "try: pass\nexcept ValueError: pass\nexcept* TypeError as e: pass\n",
14 "try: pass\nexcept* ValueError: pass\nexcept TypeError as e: pass\n",
15 "try: pass\nexcept ValueError: pass\nexcept*: pass\n",
16 "try: pass\nexcept* ValueError: pass\nexcept: pass\n",
17 ]
18
19 for err in errors:
20 with self.assertRaises(SyntaxError):
21 compile(err, "<string>", "exec")
22
23 def test_except_star_ExceptionGroup_is_runtime_error_single(self):
24 with self.assertRaises(TypeError):
25 try:
26 raise OSError("blah")
27 except* ExceptionGroup as e:
28 pass
29
30 def test_except_star_ExceptionGroup_is_runtime_error_tuple(self):
31 with self.assertRaises(TypeError):
32 try:
33 raise ExceptionGroup("eg", [ValueError(42)])
34 except* (TypeError, ExceptionGroup):
35 pass
36
37 def test_except_star_invalid_exception_type(self):
38 with self.assertRaises(TypeError):
39 try:
40 raise ValueError
41 except* 42:
42 pass
43
44 with self.assertRaises(TypeError):
45 try:
46 raise ValueError
47 except* (ValueError, 42):
48 pass
49
50
51 class ESC[4;38;5;81mTestBreakContinueReturnInExceptStarBlock(ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
52 MSG = (r"'break', 'continue' and 'return'"
53 r" cannot appear in an except\* block")
54
55 def check_invalid(self, src):
56 with self.assertRaisesRegex(SyntaxError, self.MSG):
57 compile(textwrap.dedent(src), "<string>", "exec")
58
59 def test_break_in_except_star(self):
60 self.check_invalid(
61 """
62 try:
63 raise ValueError
64 except* Exception as e:
65 break
66 """)
67
68 self.check_invalid(
69 """
70 for i in range(5):
71 try:
72 pass
73 except* Exception as e:
74 if i == 2:
75 break
76 """)
77
78 self.check_invalid(
79 """
80 for i in range(5):
81 try:
82 pass
83 except* Exception as e:
84 if i == 2:
85 break
86 finally:
87 return 0
88 """)
89
90
91 def test_continue_in_except_star_block_invalid(self):
92 self.check_invalid(
93 """
94 for i in range(5):
95 try:
96 raise ValueError
97 except* Exception as e:
98 continue
99 """)
100
101 self.check_invalid(
102 """
103 for i in range(5):
104 try:
105 pass
106 except* Exception as e:
107 if i == 2:
108 continue
109 """)
110
111 self.check_invalid(
112 """
113 for i in range(5):
114 try:
115 pass
116 except* Exception as e:
117 if i == 2:
118 continue
119 finally:
120 return 0
121 """)
122
123 def test_return_in_except_star_block_invalid(self):
124 self.check_invalid(
125 """
126 def f():
127 try:
128 raise ValueError
129 except* Exception as e:
130 return 42
131 """)
132
133 self.check_invalid(
134 """
135 def f():
136 try:
137 pass
138 except* Exception as e:
139 return 42
140 finally:
141 finished = True
142 """)
143
144 def test_break_continue_in_except_star_block_valid(self):
145 try:
146 raise ValueError(42)
147 except* Exception as e:
148 count = 0
149 for i in range(5):
150 if i == 0:
151 continue
152 if i == 4:
153 break
154 count += 1
155
156 self.assertEqual(count, 3)
157 self.assertEqual(i, 4)
158 exc = e
159 self.assertIsInstance(exc, ExceptionGroup)
160
161 def test_return_in_except_star_block_valid(self):
162 try:
163 raise ValueError(42)
164 except* Exception as e:
165 def f(x):
166 return 2*x
167 r = f(3)
168 exc = e
169 self.assertEqual(r, 6)
170 self.assertIsInstance(exc, ExceptionGroup)
171
172
173 class ESC[4;38;5;81mExceptStarTest(ESC[4;38;5;149mExceptionIsLikeMixin, ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
174 def assertMetadataEqual(self, e1, e2):
175 if e1 is None or e2 is None:
176 self.assertTrue(e1 is None and e2 is None)
177 else:
178 self.assertEqual(e1.__context__, e2.__context__)
179 self.assertEqual(e1.__cause__, e2.__cause__)
180 self.assertEqual(e1.__traceback__, e2.__traceback__)
181
182 def assertMetadataNotEqual(self, e1, e2):
183 if e1 is None or e2 is None:
184 self.assertNotEqual(e1, e2)
185 else:
186 return not (e1.__context__ == e2.__context__
187 and e1.__cause__ == e2.__cause__
188 and e1.__traceback__ == e2.__traceback__)
189
190
191 class ESC[4;38;5;81mTestExceptStarSplitSemantics(ESC[4;38;5;149mExceptStarTest):
192 def doSplitTestNamed(self, exc, T, match_template, rest_template):
193 initial_sys_exception = sys.exception()
194 sys_exception = match = rest = None
195 try:
196 try:
197 raise exc
198 except* T as e:
199 sys_exception = sys.exception()
200 match = e
201 except BaseException as e:
202 rest = e
203
204 self.assertEqual(sys_exception, match)
205 self.assertExceptionIsLike(match, match_template)
206 self.assertExceptionIsLike(rest, rest_template)
207 self.assertEqual(sys.exception(), initial_sys_exception)
208
209 def doSplitTestUnnamed(self, exc, T, match_template, rest_template):
210 initial_sys_exception = sys.exception()
211 sys_exception = match = rest = None
212 try:
213 try:
214 raise exc
215 except* T:
216 sys_exception = match = sys.exception()
217 else:
218 if rest_template:
219 self.fail("Exception not raised")
220 except BaseException as e:
221 rest = e
222 self.assertExceptionIsLike(match, match_template)
223 self.assertExceptionIsLike(rest, rest_template)
224 self.assertEqual(sys.exception(), initial_sys_exception)
225
226 def doSplitTestInExceptHandler(self, exc, T, match_template, rest_template):
227 try:
228 raise ExceptionGroup('eg', [TypeError(1), ValueError(2)])
229 except Exception:
230 self.doSplitTestNamed(exc, T, match_template, rest_template)
231 self.doSplitTestUnnamed(exc, T, match_template, rest_template)
232
233 def doSplitTestInExceptStarHandler(self, exc, T, match_template, rest_template):
234 try:
235 raise ExceptionGroup('eg', [TypeError(1), ValueError(2)])
236 except* Exception:
237 self.doSplitTestNamed(exc, T, match_template, rest_template)
238 self.doSplitTestUnnamed(exc, T, match_template, rest_template)
239
240 def doSplitTest(self, exc, T, match_template, rest_template):
241 self.doSplitTestNamed(exc, T, match_template, rest_template)
242 self.doSplitTestUnnamed(exc, T, match_template, rest_template)
243 self.doSplitTestInExceptHandler(exc, T, match_template, rest_template)
244 self.doSplitTestInExceptStarHandler(exc, T, match_template, rest_template)
245
246 def test_no_match_single_type(self):
247 self.doSplitTest(
248 ExceptionGroup("test1", [ValueError("V"), TypeError("T")]),
249 SyntaxError,
250 None,
251 ExceptionGroup("test1", [ValueError("V"), TypeError("T")]))
252
253 def test_match_single_type(self):
254 self.doSplitTest(
255 ExceptionGroup("test2", [ValueError("V1"), ValueError("V2")]),
256 ValueError,
257 ExceptionGroup("test2", [ValueError("V1"), ValueError("V2")]),
258 None)
259
260 def test_match_single_type_partial_match(self):
261 self.doSplitTest(
262 ExceptionGroup(
263 "test3",
264 [ValueError("V1"), OSError("OS"), ValueError("V2")]),
265 ValueError,
266 ExceptionGroup("test3", [ValueError("V1"), ValueError("V2")]),
267 ExceptionGroup("test3", [OSError("OS")]))
268
269 def test_match_single_type_nested(self):
270 self.doSplitTest(
271 ExceptionGroup(
272 "g1", [
273 ValueError("V1"),
274 OSError("OS1"),
275 ExceptionGroup(
276 "g2", [
277 OSError("OS2"),
278 ValueError("V2"),
279 TypeError("T")])]),
280 ValueError,
281 ExceptionGroup(
282 "g1", [
283 ValueError("V1"),
284 ExceptionGroup("g2", [ValueError("V2")])]),
285 ExceptionGroup("g1", [
286 OSError("OS1"),
287 ExceptionGroup("g2", [
288 OSError("OS2"), TypeError("T")])]))
289
290 def test_match_type_tuple_nested(self):
291 self.doSplitTest(
292 ExceptionGroup(
293 "h1", [
294 ValueError("V1"),
295 OSError("OS1"),
296 ExceptionGroup(
297 "h2", [OSError("OS2"), ValueError("V2"), TypeError("T")])]),
298 (ValueError, TypeError),
299 ExceptionGroup(
300 "h1", [
301 ValueError("V1"),
302 ExceptionGroup("h2", [ValueError("V2"), TypeError("T")])]),
303 ExceptionGroup(
304 "h1", [
305 OSError("OS1"),
306 ExceptionGroup("h2", [OSError("OS2")])]))
307
308 def test_empty_groups_removed(self):
309 self.doSplitTest(
310 ExceptionGroup(
311 "eg", [
312 ExceptionGroup("i1", [ValueError("V1")]),
313 ExceptionGroup("i2", [ValueError("V2"), TypeError("T1")]),
314 ExceptionGroup("i3", [TypeError("T2")])]),
315 TypeError,
316 ExceptionGroup("eg", [
317 ExceptionGroup("i2", [TypeError("T1")]),
318 ExceptionGroup("i3", [TypeError("T2")])]),
319 ExceptionGroup("eg", [
320 ExceptionGroup("i1", [ValueError("V1")]),
321 ExceptionGroup("i2", [ValueError("V2")])]))
322
323 def test_singleton_groups_are_kept(self):
324 self.doSplitTest(
325 ExceptionGroup("j1", [
326 ExceptionGroup("j2", [
327 ExceptionGroup("j3", [ValueError("V1")]),
328 ExceptionGroup("j4", [TypeError("T")])])]),
329 TypeError,
330 ExceptionGroup(
331 "j1",
332 [ExceptionGroup("j2", [ExceptionGroup("j4", [TypeError("T")])])]),
333 ExceptionGroup(
334 "j1",
335 [ExceptionGroup("j2", [ExceptionGroup("j3", [ValueError("V1")])])]))
336
337 def test_naked_exception_matched_wrapped1(self):
338 self.doSplitTest(
339 ValueError("V"),
340 ValueError,
341 ExceptionGroup("", [ValueError("V")]),
342 None)
343
344 def test_naked_exception_matched_wrapped2(self):
345 self.doSplitTest(
346 ValueError("V"),
347 Exception,
348 ExceptionGroup("", [ValueError("V")]),
349 None)
350
351 def test_exception_group_except_star_Exception_not_wrapped(self):
352 self.doSplitTest(
353 ExceptionGroup("eg", [ValueError("V")]),
354 Exception,
355 ExceptionGroup("eg", [ValueError("V")]),
356 None)
357
358 def test_plain_exception_not_matched(self):
359 self.doSplitTest(
360 ValueError("V"),
361 TypeError,
362 None,
363 ValueError("V"))
364
365 def test_match__supertype(self):
366 self.doSplitTest(
367 ExceptionGroup("st", [BlockingIOError("io"), TypeError("T")]),
368 OSError,
369 ExceptionGroup("st", [BlockingIOError("io")]),
370 ExceptionGroup("st", [TypeError("T")]))
371
372 def test_multiple_matches_named(self):
373 try:
374 raise ExceptionGroup("mmn", [OSError("os"), BlockingIOError("io")])
375 except* BlockingIOError as e:
376 self.assertExceptionIsLike(e,
377 ExceptionGroup("mmn", [BlockingIOError("io")]))
378 except* OSError as e:
379 self.assertExceptionIsLike(e,
380 ExceptionGroup("mmn", [OSError("os")]))
381 else:
382 self.fail("Exception not raised")
383
384 def test_multiple_matches_unnamed(self):
385 try:
386 raise ExceptionGroup("mmu", [OSError("os"), BlockingIOError("io")])
387 except* BlockingIOError:
388 e = sys.exception()
389 self.assertExceptionIsLike(e,
390 ExceptionGroup("mmu", [BlockingIOError("io")]))
391 except* OSError:
392 e = sys.exception()
393 self.assertExceptionIsLike(e,
394 ExceptionGroup("mmu", [OSError("os")]))
395 else:
396 self.fail("Exception not raised")
397
398 def test_first_match_wins_named(self):
399 try:
400 raise ExceptionGroup("fst", [BlockingIOError("io")])
401 except* OSError as e:
402 self.assertExceptionIsLike(e,
403 ExceptionGroup("fst", [BlockingIOError("io")]))
404 except* BlockingIOError:
405 self.fail("Should have been matched as OSError")
406 else:
407 self.fail("Exception not raised")
408
409 def test_first_match_wins_unnamed(self):
410 try:
411 raise ExceptionGroup("fstu", [BlockingIOError("io")])
412 except* OSError:
413 e = sys.exception()
414 self.assertExceptionIsLike(e,
415 ExceptionGroup("fstu", [BlockingIOError("io")]))
416 except* BlockingIOError:
417 pass
418 else:
419 self.fail("Exception not raised")
420
421 def test_nested_except_stars(self):
422 try:
423 raise ExceptionGroup("n", [BlockingIOError("io")])
424 except* BlockingIOError:
425 try:
426 raise ExceptionGroup("n", [ValueError("io")])
427 except* ValueError:
428 pass
429 else:
430 self.fail("Exception not raised")
431 e = sys.exception()
432 self.assertExceptionIsLike(e,
433 ExceptionGroup("n", [BlockingIOError("io")]))
434 else:
435 self.fail("Exception not raised")
436
437 def test_nested_in_loop(self):
438 for _ in range(2):
439 try:
440 raise ExceptionGroup("nl", [BlockingIOError("io")])
441 except* BlockingIOError:
442 pass
443 else:
444 self.fail("Exception not raised")
445
446
447 class ESC[4;38;5;81mTestExceptStarReraise(ESC[4;38;5;149mExceptStarTest):
448 def test_reraise_all_named(self):
449 try:
450 try:
451 raise ExceptionGroup(
452 "eg", [TypeError(1), ValueError(2), OSError(3)])
453 except* TypeError as e:
454 raise
455 except* ValueError as e:
456 raise
457 # OSError not handled
458 except ExceptionGroup as e:
459 exc = e
460
461 self.assertExceptionIsLike(
462 exc,
463 ExceptionGroup("eg", [TypeError(1), ValueError(2), OSError(3)]))
464
465 def test_reraise_all_unnamed(self):
466 try:
467 try:
468 raise ExceptionGroup(
469 "eg", [TypeError(1), ValueError(2), OSError(3)])
470 except* TypeError:
471 raise
472 except* ValueError:
473 raise
474 # OSError not handled
475 except ExceptionGroup as e:
476 exc = e
477
478 self.assertExceptionIsLike(
479 exc,
480 ExceptionGroup("eg", [TypeError(1), ValueError(2), OSError(3)]))
481
482 def test_reraise_some_handle_all_named(self):
483 try:
484 try:
485 raise ExceptionGroup(
486 "eg", [TypeError(1), ValueError(2), OSError(3)])
487 except* TypeError as e:
488 raise
489 except* ValueError as e:
490 pass
491 # OSError not handled
492 except ExceptionGroup as e:
493 exc = e
494
495 self.assertExceptionIsLike(
496 exc, ExceptionGroup("eg", [TypeError(1), OSError(3)]))
497
498 def test_reraise_partial_handle_all_unnamed(self):
499 try:
500 try:
501 raise ExceptionGroup(
502 "eg", [TypeError(1), ValueError(2)])
503 except* TypeError:
504 raise
505 except* ValueError:
506 pass
507 except ExceptionGroup as e:
508 exc = e
509
510 self.assertExceptionIsLike(
511 exc, ExceptionGroup("eg", [TypeError(1)]))
512
513 def test_reraise_partial_handle_some_named(self):
514 try:
515 try:
516 raise ExceptionGroup(
517 "eg", [TypeError(1), ValueError(2), OSError(3)])
518 except* TypeError as e:
519 raise
520 except* ValueError as e:
521 pass
522 # OSError not handled
523 except ExceptionGroup as e:
524 exc = e
525
526 self.assertExceptionIsLike(
527 exc, ExceptionGroup("eg", [TypeError(1), OSError(3)]))
528
529 def test_reraise_partial_handle_some_unnamed(self):
530 try:
531 try:
532 raise ExceptionGroup(
533 "eg", [TypeError(1), ValueError(2), OSError(3)])
534 except* TypeError:
535 raise
536 except* ValueError:
537 pass
538 except ExceptionGroup as e:
539 exc = e
540
541 self.assertExceptionIsLike(
542 exc, ExceptionGroup("eg", [TypeError(1), OSError(3)]))
543
544 def test_reraise_plain_exception_named(self):
545 try:
546 try:
547 raise ValueError(42)
548 except* ValueError as e:
549 raise
550 except ExceptionGroup as e:
551 exc = e
552
553 self.assertExceptionIsLike(
554 exc, ExceptionGroup("", [ValueError(42)]))
555
556 def test_reraise_plain_exception_unnamed(self):
557 try:
558 try:
559 raise ValueError(42)
560 except* ValueError:
561 raise
562 except ExceptionGroup as e:
563 exc = e
564
565 self.assertExceptionIsLike(
566 exc, ExceptionGroup("", [ValueError(42)]))
567
568
569 class ESC[4;38;5;81mTestExceptStarRaise(ESC[4;38;5;149mExceptStarTest):
570 def test_raise_named(self):
571 orig = ExceptionGroup("eg", [ValueError(1), OSError(2)])
572 try:
573 try:
574 raise orig
575 except* OSError as e:
576 raise TypeError(3)
577 except ExceptionGroup as e:
578 exc = e
579
580 self.assertExceptionIsLike(
581 exc,
582 ExceptionGroup(
583 "", [TypeError(3), ExceptionGroup("eg", [ValueError(1)])]))
584
585 self.assertExceptionIsLike(
586 exc.exceptions[0].__context__,
587 ExceptionGroup("eg", [OSError(2)]))
588
589 self.assertMetadataNotEqual(orig, exc)
590 self.assertMetadataEqual(orig, exc.exceptions[0].__context__)
591
592 def test_raise_unnamed(self):
593 orig = ExceptionGroup("eg", [ValueError(1), OSError(2)])
594 try:
595 try:
596 raise orig
597 except* OSError:
598 raise TypeError(3)
599 except ExceptionGroup as e:
600 exc = e
601
602 self.assertExceptionIsLike(
603 exc,
604 ExceptionGroup(
605 "", [TypeError(3), ExceptionGroup("eg", [ValueError(1)])]))
606
607 self.assertExceptionIsLike(
608 exc.exceptions[0].__context__,
609 ExceptionGroup("eg", [OSError(2)]))
610
611 self.assertMetadataNotEqual(orig, exc)
612 self.assertMetadataEqual(orig, exc.exceptions[0].__context__)
613
614 def test_raise_handle_all_raise_one_named(self):
615 orig = ExceptionGroup("eg", [TypeError(1), ValueError(2)])
616 try:
617 try:
618 raise orig
619 except* (TypeError, ValueError) as e:
620 raise SyntaxError(3)
621 except SyntaxError as e:
622 exc = e
623
624 self.assertExceptionIsLike(exc, SyntaxError(3))
625
626 self.assertExceptionIsLike(
627 exc.__context__,
628 ExceptionGroup("eg", [TypeError(1), ValueError(2)]))
629
630 self.assertMetadataNotEqual(orig, exc)
631 self.assertMetadataEqual(orig, exc.__context__)
632
633 def test_raise_handle_all_raise_one_unnamed(self):
634 orig = ExceptionGroup("eg", [TypeError(1), ValueError(2)])
635 try:
636 try:
637 raise orig
638 except* (TypeError, ValueError) as e:
639 raise SyntaxError(3)
640 except SyntaxError as e:
641 exc = e
642
643 self.assertExceptionIsLike(exc, SyntaxError(3))
644
645 self.assertExceptionIsLike(
646 exc.__context__,
647 ExceptionGroup("eg", [TypeError(1), ValueError(2)]))
648
649 self.assertMetadataNotEqual(orig, exc)
650 self.assertMetadataEqual(orig, exc.__context__)
651
652 def test_raise_handle_all_raise_two_named(self):
653 orig = ExceptionGroup("eg", [TypeError(1), ValueError(2)])
654 try:
655 try:
656 raise orig
657 except* TypeError as e:
658 raise SyntaxError(3)
659 except* ValueError as e:
660 raise SyntaxError(4)
661 except ExceptionGroup as e:
662 exc = e
663
664 self.assertExceptionIsLike(
665 exc, ExceptionGroup("", [SyntaxError(3), SyntaxError(4)]))
666
667 self.assertExceptionIsLike(
668 exc.exceptions[0].__context__,
669 ExceptionGroup("eg", [TypeError(1)]))
670
671 self.assertExceptionIsLike(
672 exc.exceptions[1].__context__,
673 ExceptionGroup("eg", [ValueError(2)]))
674
675 self.assertMetadataNotEqual(orig, exc)
676 self.assertMetadataEqual(orig, exc.exceptions[0].__context__)
677 self.assertMetadataEqual(orig, exc.exceptions[1].__context__)
678
679 def test_raise_handle_all_raise_two_unnamed(self):
680 orig = ExceptionGroup("eg", [TypeError(1), ValueError(2)])
681 try:
682 try:
683 raise orig
684 except* TypeError:
685 raise SyntaxError(3)
686 except* ValueError:
687 raise SyntaxError(4)
688 except ExceptionGroup as e:
689 exc = e
690
691 self.assertExceptionIsLike(
692 exc, ExceptionGroup("", [SyntaxError(3), SyntaxError(4)]))
693
694 self.assertExceptionIsLike(
695 exc.exceptions[0].__context__,
696 ExceptionGroup("eg", [TypeError(1)]))
697
698 self.assertExceptionIsLike(
699 exc.exceptions[1].__context__,
700 ExceptionGroup("eg", [ValueError(2)]))
701
702 self.assertMetadataNotEqual(orig, exc)
703 self.assertMetadataEqual(orig, exc.exceptions[0].__context__)
704 self.assertMetadataEqual(orig, exc.exceptions[1].__context__)
705
706
707 class ESC[4;38;5;81mTestExceptStarRaiseFrom(ESC[4;38;5;149mExceptStarTest):
708 def test_raise_named(self):
709 orig = ExceptionGroup("eg", [ValueError(1), OSError(2)])
710 try:
711 try:
712 raise orig
713 except* OSError as e:
714 raise TypeError(3) from e
715 except ExceptionGroup as e:
716 exc = e
717
718 self.assertExceptionIsLike(
719 exc,
720 ExceptionGroup(
721 "", [TypeError(3), ExceptionGroup("eg", [ValueError(1)])]))
722
723 self.assertExceptionIsLike(
724 exc.exceptions[0].__context__,
725 ExceptionGroup("eg", [OSError(2)]))
726
727 self.assertExceptionIsLike(
728 exc.exceptions[0].__cause__,
729 ExceptionGroup("eg", [OSError(2)]))
730
731 self.assertMetadataNotEqual(orig, exc)
732 self.assertMetadataEqual(orig, exc.exceptions[0].__context__)
733 self.assertMetadataEqual(orig, exc.exceptions[0].__cause__)
734 self.assertMetadataNotEqual(orig, exc.exceptions[1].__context__)
735 self.assertMetadataNotEqual(orig, exc.exceptions[1].__cause__)
736
737 def test_raise_unnamed(self):
738 orig = ExceptionGroup("eg", [ValueError(1), OSError(2)])
739 try:
740 try:
741 raise orig
742 except* OSError:
743 e = sys.exception()
744 raise TypeError(3) from e
745 except ExceptionGroup as e:
746 exc = e
747
748 self.assertExceptionIsLike(
749 exc,
750 ExceptionGroup(
751 "", [TypeError(3), ExceptionGroup("eg", [ValueError(1)])]))
752
753 self.assertExceptionIsLike(
754 exc.exceptions[0].__context__,
755 ExceptionGroup("eg", [OSError(2)]))
756
757 self.assertExceptionIsLike(
758 exc.exceptions[0].__cause__,
759 ExceptionGroup("eg", [OSError(2)]))
760
761 self.assertMetadataNotEqual(orig, exc)
762 self.assertMetadataEqual(orig, exc.exceptions[0].__context__)
763 self.assertMetadataEqual(orig, exc.exceptions[0].__cause__)
764 self.assertMetadataNotEqual(orig, exc.exceptions[1].__context__)
765 self.assertMetadataNotEqual(orig, exc.exceptions[1].__cause__)
766
767 def test_raise_handle_all_raise_one_named(self):
768 orig = ExceptionGroup("eg", [TypeError(1), ValueError(2)])
769 try:
770 try:
771 raise orig
772 except* (TypeError, ValueError) as e:
773 raise SyntaxError(3) from e
774 except SyntaxError as e:
775 exc = e
776
777 self.assertExceptionIsLike(exc, SyntaxError(3))
778
779 self.assertExceptionIsLike(
780 exc.__context__,
781 ExceptionGroup("eg", [TypeError(1), ValueError(2)]))
782
783 self.assertExceptionIsLike(
784 exc.__cause__,
785 ExceptionGroup("eg", [TypeError(1), ValueError(2)]))
786
787 self.assertMetadataNotEqual(orig, exc)
788 self.assertMetadataEqual(orig, exc.__context__)
789 self.assertMetadataEqual(orig, exc.__cause__)
790
791 def test_raise_handle_all_raise_one_unnamed(self):
792 orig = ExceptionGroup("eg", [TypeError(1), ValueError(2)])
793 try:
794 try:
795 raise orig
796 except* (TypeError, ValueError) as e:
797 e = sys.exception()
798 raise SyntaxError(3) from e
799 except SyntaxError as e:
800 exc = e
801
802 self.assertExceptionIsLike(exc, SyntaxError(3))
803
804 self.assertExceptionIsLike(
805 exc.__context__,
806 ExceptionGroup("eg", [TypeError(1), ValueError(2)]))
807
808 self.assertExceptionIsLike(
809 exc.__cause__,
810 ExceptionGroup("eg", [TypeError(1), ValueError(2)]))
811
812 self.assertMetadataNotEqual(orig, exc)
813 self.assertMetadataEqual(orig, exc.__context__)
814 self.assertMetadataEqual(orig, exc.__cause__)
815
816 def test_raise_handle_all_raise_two_named(self):
817 orig = ExceptionGroup("eg", [TypeError(1), ValueError(2)])
818 try:
819 try:
820 raise orig
821 except* TypeError as e:
822 raise SyntaxError(3) from e
823 except* ValueError as e:
824 raise SyntaxError(4) from e
825 except ExceptionGroup as e:
826 exc = e
827
828 self.assertExceptionIsLike(
829 exc, ExceptionGroup("", [SyntaxError(3), SyntaxError(4)]))
830
831 self.assertExceptionIsLike(
832 exc.exceptions[0].__context__,
833 ExceptionGroup("eg", [TypeError(1)]))
834
835 self.assertExceptionIsLike(
836 exc.exceptions[0].__cause__,
837 ExceptionGroup("eg", [TypeError(1)]))
838
839 self.assertExceptionIsLike(
840 exc.exceptions[1].__context__,
841 ExceptionGroup("eg", [ValueError(2)]))
842
843 self.assertExceptionIsLike(
844 exc.exceptions[1].__cause__,
845 ExceptionGroup("eg", [ValueError(2)]))
846
847 self.assertMetadataNotEqual(orig, exc)
848 self.assertMetadataEqual(orig, exc.exceptions[0].__context__)
849 self.assertMetadataEqual(orig, exc.exceptions[0].__cause__)
850
851 def test_raise_handle_all_raise_two_unnamed(self):
852 orig = ExceptionGroup("eg", [TypeError(1), ValueError(2)])
853 try:
854 try:
855 raise orig
856 except* TypeError:
857 e = sys.exception()
858 raise SyntaxError(3) from e
859 except* ValueError:
860 e = sys.exception()
861 raise SyntaxError(4) from e
862 except ExceptionGroup as e:
863 exc = e
864
865 self.assertExceptionIsLike(
866 exc, ExceptionGroup("", [SyntaxError(3), SyntaxError(4)]))
867
868 self.assertExceptionIsLike(
869 exc.exceptions[0].__context__,
870 ExceptionGroup("eg", [TypeError(1)]))
871
872 self.assertExceptionIsLike(
873 exc.exceptions[0].__cause__,
874 ExceptionGroup("eg", [TypeError(1)]))
875
876 self.assertExceptionIsLike(
877 exc.exceptions[1].__context__,
878 ExceptionGroup("eg", [ValueError(2)]))
879
880 self.assertExceptionIsLike(
881 exc.exceptions[1].__cause__,
882 ExceptionGroup("eg", [ValueError(2)]))
883
884 self.assertMetadataNotEqual(orig, exc)
885 self.assertMetadataEqual(orig, exc.exceptions[0].__context__)
886 self.assertMetadataEqual(orig, exc.exceptions[0].__cause__)
887 self.assertMetadataEqual(orig, exc.exceptions[1].__context__)
888 self.assertMetadataEqual(orig, exc.exceptions[1].__cause__)
889
890
891 class ESC[4;38;5;81mTestExceptStarExceptionGroupSubclass(ESC[4;38;5;149mExceptStarTest):
892 def test_except_star_EG_subclass(self):
893 class ESC[4;38;5;81mEG(ESC[4;38;5;149mExceptionGroup):
894 def __new__(cls, message, excs, code):
895 obj = super().__new__(cls, message, excs)
896 obj.code = code
897 return obj
898
899 def derive(self, excs):
900 return EG(self.message, excs, self.code)
901
902 try:
903 try:
904 try:
905 try:
906 raise TypeError(2)
907 except TypeError as te:
908 raise EG("nested", [te], 101) from None
909 except EG as nested:
910 try:
911 raise ValueError(1)
912 except ValueError as ve:
913 raise EG("eg", [ve, nested], 42)
914 except* ValueError as eg:
915 veg = eg
916 except EG as eg:
917 teg = eg
918
919 self.assertIsInstance(veg, EG)
920 self.assertIsInstance(teg, EG)
921 self.assertIsInstance(teg.exceptions[0], EG)
922 self.assertMetadataEqual(veg, teg)
923 self.assertEqual(veg.code, 42)
924 self.assertEqual(teg.code, 42)
925 self.assertEqual(teg.exceptions[0].code, 101)
926
927 def test_falsy_exception_group_subclass(self):
928 class ESC[4;38;5;81mFalsyEG(ESC[4;38;5;149mExceptionGroup):
929 def __bool__(self):
930 return False
931
932 def derive(self, excs):
933 return FalsyEG(self.message, excs)
934
935 try:
936 try:
937 raise FalsyEG("eg", [TypeError(1), ValueError(2)])
938 except *TypeError as e:
939 tes = e
940 raise
941 except *ValueError as e:
942 ves = e
943 pass
944 except Exception as e:
945 exc = e
946
947 for e in [tes, ves, exc]:
948 self.assertFalse(e)
949 self.assertIsInstance(e, FalsyEG)
950
951 self.assertExceptionIsLike(exc, FalsyEG("eg", [TypeError(1)]))
952 self.assertExceptionIsLike(tes, FalsyEG("eg", [TypeError(1)]))
953 self.assertExceptionIsLike(ves, FalsyEG("eg", [ValueError(2)]))
954
955
956 class ESC[4;38;5;81mTestExceptStarCleanup(ESC[4;38;5;149mExceptStarTest):
957 def test_sys_exception_restored(self):
958 try:
959 try:
960 raise ValueError(42)
961 except:
962 try:
963 raise TypeError(int)
964 except* Exception:
965 pass
966 1/0
967 except Exception as e:
968 exc = e
969
970 self.assertExceptionIsLike(exc, ZeroDivisionError('division by zero'))
971 self.assertExceptionIsLike(exc.__context__, ValueError(42))
972 self.assertEqual(sys.exception(), None)
973
974
975 class ESC[4;38;5;81mTestExceptStar_WeirdLeafExceptions(ESC[4;38;5;149mExceptStarTest):
976 # Test that except* works when leaf exceptions are
977 # unhashable or have a bad custom __eq__
978
979 class ESC[4;38;5;81mUnhashableExc(ESC[4;38;5;149mValueError):
980 __hash__ = None
981
982 class ESC[4;38;5;81mAlwaysEqualExc(ESC[4;38;5;149mValueError):
983 def __eq__(self, other):
984 return True
985
986 class ESC[4;38;5;81mNeverEqualExc(ESC[4;38;5;149mValueError):
987 def __eq__(self, other):
988 return False
989
990 class ESC[4;38;5;81mBrokenEqualExc(ESC[4;38;5;149mValueError):
991 def __eq__(self, other):
992 raise RuntimeError()
993
994 def setUp(self):
995 self.bad_types = [self.UnhashableExc,
996 self.AlwaysEqualExc,
997 self.NeverEqualExc,
998 self.BrokenEqualExc]
999
1000 def except_type(self, eg, type):
1001 match, rest = None, None
1002 try:
1003 try:
1004 raise eg
1005 except* type as e:
1006 match = e
1007 except Exception as e:
1008 rest = e
1009 return match, rest
1010
1011 def test_catch_unhashable_leaf_exception(self):
1012 for Bad in self.bad_types:
1013 with self.subTest(Bad):
1014 eg = ExceptionGroup("eg", [TypeError(1), Bad(2)])
1015 match, rest = self.except_type(eg, Bad)
1016 self.assertExceptionIsLike(
1017 match, ExceptionGroup("eg", [Bad(2)]))
1018 self.assertExceptionIsLike(
1019 rest, ExceptionGroup("eg", [TypeError(1)]))
1020
1021 def test_propagate_unhashable_leaf(self):
1022 for Bad in self.bad_types:
1023 with self.subTest(Bad):
1024 eg = ExceptionGroup("eg", [TypeError(1), Bad(2)])
1025 match, rest = self.except_type(eg, TypeError)
1026 self.assertExceptionIsLike(
1027 match, ExceptionGroup("eg", [TypeError(1)]))
1028 self.assertExceptionIsLike(
1029 rest, ExceptionGroup("eg", [Bad(2)]))
1030
1031 def test_catch_nothing_unhashable_leaf(self):
1032 for Bad in self.bad_types:
1033 with self.subTest(Bad):
1034 eg = ExceptionGroup("eg", [TypeError(1), Bad(2)])
1035 match, rest = self.except_type(eg, OSError)
1036 self.assertIsNone(match)
1037 self.assertExceptionIsLike(rest, eg)
1038
1039 def test_catch_everything_unhashable_leaf(self):
1040 for Bad in self.bad_types:
1041 with self.subTest(Bad):
1042 eg = ExceptionGroup("eg", [TypeError(1), Bad(2)])
1043 match, rest = self.except_type(eg, Exception)
1044 self.assertExceptionIsLike(match, eg)
1045 self.assertIsNone(rest)
1046
1047 def test_reraise_unhashable_leaf(self):
1048 for Bad in self.bad_types:
1049 with self.subTest(Bad):
1050 eg = ExceptionGroup(
1051 "eg", [TypeError(1), Bad(2), ValueError(3)])
1052
1053 try:
1054 try:
1055 raise eg
1056 except* TypeError:
1057 pass
1058 except* Bad:
1059 raise
1060 except Exception as e:
1061 exc = e
1062
1063 self.assertExceptionIsLike(
1064 exc, ExceptionGroup("eg", [Bad(2), ValueError(3)]))
1065
1066
1067 class ESC[4;38;5;81mTestExceptStar_WeirdExceptionGroupSubclass(ESC[4;38;5;149mExceptStarTest):
1068 # Test that except* works with exception groups that are
1069 # unhashable or have a bad custom __eq__
1070
1071 class ESC[4;38;5;81mUnhashableEG(ESC[4;38;5;149mExceptionGroup):
1072 __hash__ = None
1073
1074 def derive(self, excs):
1075 return type(self)(self.message, excs)
1076
1077 class ESC[4;38;5;81mAlwaysEqualEG(ESC[4;38;5;149mExceptionGroup):
1078 def __eq__(self, other):
1079 return True
1080
1081 def derive(self, excs):
1082 return type(self)(self.message, excs)
1083
1084 class ESC[4;38;5;81mNeverEqualEG(ESC[4;38;5;149mExceptionGroup):
1085 def __eq__(self, other):
1086 return False
1087
1088 def derive(self, excs):
1089 return type(self)(self.message, excs)
1090
1091 class ESC[4;38;5;81mBrokenEqualEG(ESC[4;38;5;149mExceptionGroup):
1092 def __eq__(self, other):
1093 raise RuntimeError()
1094
1095 def derive(self, excs):
1096 return type(self)(self.message, excs)
1097
1098 def setUp(self):
1099 self.bad_types = [self.UnhashableEG,
1100 self.AlwaysEqualEG,
1101 self.NeverEqualEG,
1102 self.BrokenEqualEG]
1103
1104 def except_type(self, eg, type):
1105 match, rest = None, None
1106 try:
1107 try:
1108 raise eg
1109 except* type as e:
1110 match = e
1111 except Exception as e:
1112 rest = e
1113 return match, rest
1114
1115 def test_catch_some_unhashable_exception_group_subclass(self):
1116 for BadEG in self.bad_types:
1117 with self.subTest(BadEG):
1118 eg = BadEG("eg",
1119 [TypeError(1),
1120 BadEG("nested", [ValueError(2)])])
1121
1122 match, rest = self.except_type(eg, TypeError)
1123 self.assertExceptionIsLike(match, BadEG("eg", [TypeError(1)]))
1124 self.assertExceptionIsLike(rest,
1125 BadEG("eg", [BadEG("nested", [ValueError(2)])]))
1126
1127 def test_catch_none_unhashable_exception_group_subclass(self):
1128 for BadEG in self.bad_types:
1129 with self.subTest(BadEG):
1130
1131 eg = BadEG("eg",
1132 [TypeError(1),
1133 BadEG("nested", [ValueError(2)])])
1134
1135 match, rest = self.except_type(eg, OSError)
1136 self.assertIsNone(match)
1137 self.assertExceptionIsLike(rest, eg)
1138
1139 def test_catch_all_unhashable_exception_group_subclass(self):
1140 for BadEG in self.bad_types:
1141 with self.subTest(BadEG):
1142
1143 eg = BadEG("eg",
1144 [TypeError(1),
1145 BadEG("nested", [ValueError(2)])])
1146
1147 match, rest = self.except_type(eg, Exception)
1148 self.assertExceptionIsLike(match, eg)
1149 self.assertIsNone(rest)
1150
1151 def test_reraise_unhashable_eg(self):
1152 for BadEG in self.bad_types:
1153 with self.subTest(BadEG):
1154
1155 eg = BadEG("eg",
1156 [TypeError(1), ValueError(2),
1157 BadEG("nested", [ValueError(3), OSError(4)])])
1158
1159 try:
1160 try:
1161 raise eg
1162 except* ValueError:
1163 pass
1164 except* OSError:
1165 raise
1166 except Exception as e:
1167 exc = e
1168
1169 self.assertExceptionIsLike(
1170 exc, BadEG("eg", [TypeError(1),
1171 BadEG("nested", [OSError(4)])]))
1172
1173
1174 if __name__ == '__main__':
1175 unittest.main()