python (3.12.0)

(root)/
lib/
python3.12/
test/
test_except_star.py
       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()