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