(root)/
Python-3.12.0/
Lib/
test/
test_raise.py
       1  # Copyright 2007 Google, Inc. All Rights Reserved.
       2  # Licensed to PSF under a Contributor Agreement.
       3  
       4  """Tests for the raise statement."""
       5  
       6  from test import support
       7  import sys
       8  import types
       9  import unittest
      10  
      11  
      12  def get_tb():
      13      try:
      14          raise OSError()
      15      except OSError as e:
      16          return e.__traceback__
      17  
      18  
      19  class ESC[4;38;5;81mContext:
      20      def __enter__(self):
      21          return self
      22      def __exit__(self, exc_type, exc_value, exc_tb):
      23          return True
      24  
      25  
      26  class ESC[4;38;5;81mTestRaise(ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
      27      def test_invalid_reraise(self):
      28          try:
      29              raise
      30          except RuntimeError as e:
      31              self.assertIn("No active exception", str(e))
      32          else:
      33              self.fail("No exception raised")
      34  
      35      def test_reraise(self):
      36          try:
      37              try:
      38                  raise IndexError()
      39              except IndexError as e:
      40                  exc1 = e
      41                  raise
      42          except IndexError as exc2:
      43              self.assertIs(exc1, exc2)
      44          else:
      45              self.fail("No exception raised")
      46  
      47      def test_except_reraise(self):
      48          def reraise():
      49              try:
      50                  raise TypeError("foo")
      51              except:
      52                  try:
      53                      raise KeyError("caught")
      54                  except KeyError:
      55                      pass
      56                  raise
      57          self.assertRaises(TypeError, reraise)
      58  
      59      def test_finally_reraise(self):
      60          def reraise():
      61              try:
      62                  raise TypeError("foo")
      63              except:
      64                  try:
      65                      raise KeyError("caught")
      66                  finally:
      67                      raise
      68          self.assertRaises(KeyError, reraise)
      69  
      70      def test_nested_reraise(self):
      71          def nested_reraise():
      72              raise
      73          def reraise():
      74              try:
      75                  raise TypeError("foo")
      76              except:
      77                  nested_reraise()
      78          self.assertRaises(TypeError, reraise)
      79  
      80      def test_raise_from_None(self):
      81          try:
      82              try:
      83                  raise TypeError("foo")
      84              except:
      85                  raise ValueError() from None
      86          except ValueError as e:
      87              self.assertIsInstance(e.__context__, TypeError)
      88              self.assertIsNone(e.__cause__)
      89  
      90      def test_with_reraise1(self):
      91          def reraise():
      92              try:
      93                  raise TypeError("foo")
      94              except:
      95                  with Context():
      96                      pass
      97                  raise
      98          self.assertRaises(TypeError, reraise)
      99  
     100      def test_with_reraise2(self):
     101          def reraise():
     102              try:
     103                  raise TypeError("foo")
     104              except:
     105                  with Context():
     106                      raise KeyError("caught")
     107                  raise
     108          self.assertRaises(TypeError, reraise)
     109  
     110      def test_yield_reraise(self):
     111          def reraise():
     112              try:
     113                  raise TypeError("foo")
     114              except:
     115                  yield 1
     116                  raise
     117          g = reraise()
     118          next(g)
     119          self.assertRaises(TypeError, lambda: next(g))
     120          self.assertRaises(StopIteration, lambda: next(g))
     121  
     122      def test_erroneous_exception(self):
     123          class ESC[4;38;5;81mMyException(ESC[4;38;5;149mException):
     124              def __init__(self):
     125                  raise RuntimeError()
     126  
     127          try:
     128              raise MyException
     129          except RuntimeError:
     130              pass
     131          else:
     132              self.fail("No exception raised")
     133  
     134      def test_new_returns_invalid_instance(self):
     135          # See issue #11627.
     136          class ESC[4;38;5;81mMyException(ESC[4;38;5;149mException):
     137              def __new__(cls, *args):
     138                  return object()
     139  
     140          with self.assertRaises(TypeError):
     141              raise MyException
     142  
     143      def test_assert_with_tuple_arg(self):
     144          try:
     145              assert False, (3,)
     146          except AssertionError as e:
     147              self.assertEqual(str(e), "(3,)")
     148  
     149  
     150  
     151  class ESC[4;38;5;81mTestCause(ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
     152  
     153      def testCauseSyntax(self):
     154          try:
     155              try:
     156                  try:
     157                      raise TypeError
     158                  except Exception:
     159                      raise ValueError from None
     160              except ValueError as exc:
     161                  self.assertIsNone(exc.__cause__)
     162                  self.assertTrue(exc.__suppress_context__)
     163                  exc.__suppress_context__ = False
     164                  raise exc
     165          except ValueError as exc:
     166              e = exc
     167  
     168          self.assertIsNone(e.__cause__)
     169          self.assertFalse(e.__suppress_context__)
     170          self.assertIsInstance(e.__context__, TypeError)
     171  
     172      def test_invalid_cause(self):
     173          try:
     174              raise IndexError from 5
     175          except TypeError as e:
     176              self.assertIn("exception cause", str(e))
     177          else:
     178              self.fail("No exception raised")
     179  
     180      def test_class_cause(self):
     181          try:
     182              raise IndexError from KeyError
     183          except IndexError as e:
     184              self.assertIsInstance(e.__cause__, KeyError)
     185          else:
     186              self.fail("No exception raised")
     187  
     188      def test_instance_cause(self):
     189          cause = KeyError()
     190          try:
     191              raise IndexError from cause
     192          except IndexError as e:
     193              self.assertIs(e.__cause__, cause)
     194          else:
     195              self.fail("No exception raised")
     196  
     197      def test_erroneous_cause(self):
     198          class ESC[4;38;5;81mMyException(ESC[4;38;5;149mException):
     199              def __init__(self):
     200                  raise RuntimeError()
     201  
     202          try:
     203              raise IndexError from MyException
     204          except RuntimeError:
     205              pass
     206          else:
     207              self.fail("No exception raised")
     208  
     209  
     210  class ESC[4;38;5;81mTestTraceback(ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
     211  
     212      def test_sets_traceback(self):
     213          try:
     214              raise IndexError()
     215          except IndexError as e:
     216              self.assertIsInstance(e.__traceback__, types.TracebackType)
     217          else:
     218              self.fail("No exception raised")
     219  
     220      def test_accepts_traceback(self):
     221          tb = get_tb()
     222          try:
     223              raise IndexError().with_traceback(tb)
     224          except IndexError as e:
     225              self.assertNotEqual(e.__traceback__, tb)
     226              self.assertEqual(e.__traceback__.tb_next, tb)
     227          else:
     228              self.fail("No exception raised")
     229  
     230  
     231  class ESC[4;38;5;81mTestTracebackType(ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
     232  
     233      def raiser(self):
     234          raise ValueError
     235  
     236      def test_attrs(self):
     237          try:
     238              self.raiser()
     239          except Exception as exc:
     240              tb = exc.__traceback__
     241  
     242          self.assertIsInstance(tb.tb_next, types.TracebackType)
     243          self.assertIs(tb.tb_frame, sys._getframe())
     244          self.assertIsInstance(tb.tb_lasti, int)
     245          self.assertIsInstance(tb.tb_lineno, int)
     246  
     247          self.assertIs(tb.tb_next.tb_next, None)
     248  
     249          # Invalid assignments
     250          with self.assertRaises(TypeError):
     251              del tb.tb_next
     252  
     253          with self.assertRaises(TypeError):
     254              tb.tb_next = "asdf"
     255  
     256          # Loops
     257          with self.assertRaises(ValueError):
     258              tb.tb_next = tb
     259  
     260          with self.assertRaises(ValueError):
     261              tb.tb_next.tb_next = tb
     262  
     263          # Valid assignments
     264          tb.tb_next = None
     265          self.assertIs(tb.tb_next, None)
     266  
     267          new_tb = get_tb()
     268          tb.tb_next = new_tb
     269          self.assertIs(tb.tb_next, new_tb)
     270  
     271      def test_constructor(self):
     272          other_tb = get_tb()
     273          frame = sys._getframe()
     274  
     275          tb = types.TracebackType(other_tb, frame, 1, 2)
     276          self.assertEqual(tb.tb_next, other_tb)
     277          self.assertEqual(tb.tb_frame, frame)
     278          self.assertEqual(tb.tb_lasti, 1)
     279          self.assertEqual(tb.tb_lineno, 2)
     280  
     281          tb = types.TracebackType(None, frame, 1, 2)
     282          self.assertEqual(tb.tb_next, None)
     283  
     284          with self.assertRaises(TypeError):
     285              types.TracebackType("no", frame, 1, 2)
     286  
     287          with self.assertRaises(TypeError):
     288              types.TracebackType(other_tb, "no", 1, 2)
     289  
     290          with self.assertRaises(TypeError):
     291              types.TracebackType(other_tb, frame, "no", 2)
     292  
     293          with self.assertRaises(TypeError):
     294              types.TracebackType(other_tb, frame, 1, "nuh-uh")
     295  
     296  
     297  class ESC[4;38;5;81mTestContext(ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
     298      def test_instance_context_instance_raise(self):
     299          context = IndexError()
     300          try:
     301              try:
     302                  raise context
     303              except:
     304                  raise OSError()
     305          except OSError as e:
     306              self.assertIs(e.__context__, context)
     307          else:
     308              self.fail("No exception raised")
     309  
     310      def test_class_context_instance_raise(self):
     311          context = IndexError
     312          try:
     313              try:
     314                  raise context
     315              except:
     316                  raise OSError()
     317          except OSError as e:
     318              self.assertIsNot(e.__context__, context)
     319              self.assertIsInstance(e.__context__, context)
     320          else:
     321              self.fail("No exception raised")
     322  
     323      def test_class_context_class_raise(self):
     324          context = IndexError
     325          try:
     326              try:
     327                  raise context
     328              except:
     329                  raise OSError
     330          except OSError as e:
     331              self.assertIsNot(e.__context__, context)
     332              self.assertIsInstance(e.__context__, context)
     333          else:
     334              self.fail("No exception raised")
     335  
     336      def test_c_exception_context(self):
     337          try:
     338              try:
     339                  1/0
     340              except:
     341                  raise OSError
     342          except OSError as e:
     343              self.assertIsInstance(e.__context__, ZeroDivisionError)
     344          else:
     345              self.fail("No exception raised")
     346  
     347      def test_c_exception_raise(self):
     348          try:
     349              try:
     350                  1/0
     351              except:
     352                  xyzzy
     353          except NameError as e:
     354              self.assertIsInstance(e.__context__, ZeroDivisionError)
     355          else:
     356              self.fail("No exception raised")
     357  
     358      def test_noraise_finally(self):
     359          try:
     360              try:
     361                  pass
     362              finally:
     363                  raise OSError
     364          except OSError as e:
     365              self.assertIsNone(e.__context__)
     366          else:
     367              self.fail("No exception raised")
     368  
     369      def test_raise_finally(self):
     370          try:
     371              try:
     372                  1/0
     373              finally:
     374                  raise OSError
     375          except OSError as e:
     376              self.assertIsInstance(e.__context__, ZeroDivisionError)
     377          else:
     378              self.fail("No exception raised")
     379  
     380      def test_context_manager(self):
     381          class ESC[4;38;5;81mContextManager:
     382              def __enter__(self):
     383                  pass
     384              def __exit__(self, t, v, tb):
     385                  xyzzy
     386          try:
     387              with ContextManager():
     388                  1/0
     389          except NameError as e:
     390              self.assertIsInstance(e.__context__, ZeroDivisionError)
     391          else:
     392              self.fail("No exception raised")
     393  
     394      def test_cycle_broken(self):
     395          # Self-cycles (when re-raising a caught exception) are broken
     396          try:
     397              try:
     398                  1/0
     399              except ZeroDivisionError as e:
     400                  raise e
     401          except ZeroDivisionError as e:
     402              self.assertIsNone(e.__context__)
     403  
     404      def test_reraise_cycle_broken(self):
     405          # Non-trivial context cycles (through re-raising a previous exception)
     406          # are broken too.
     407          try:
     408              try:
     409                  xyzzy
     410              except NameError as a:
     411                  try:
     412                      1/0
     413                  except ZeroDivisionError:
     414                      raise a
     415          except NameError as e:
     416              self.assertIsNone(e.__context__.__context__)
     417  
     418      def test_not_last(self):
     419          # Context is not necessarily the last exception
     420          context = Exception("context")
     421          try:
     422              raise context
     423          except Exception:
     424              try:
     425                  raise Exception("caught")
     426              except Exception:
     427                  pass
     428              try:
     429                  raise Exception("new")
     430              except Exception as exc:
     431                  raised = exc
     432          self.assertIs(raised.__context__, context)
     433  
     434      def test_3118(self):
     435          # deleting the generator caused the __context__ to be cleared
     436          def gen():
     437              try:
     438                  yield 1
     439              finally:
     440                  pass
     441  
     442          def f():
     443              g = gen()
     444              next(g)
     445              try:
     446                  try:
     447                      raise ValueError
     448                  except:
     449                      del g
     450                      raise KeyError
     451              except Exception as e:
     452                  self.assertIsInstance(e.__context__, ValueError)
     453  
     454          f()
     455  
     456      def test_3611(self):
     457          import gc
     458          # A re-raised exception in a __del__ caused the __context__
     459          # to be cleared
     460          class ESC[4;38;5;81mC:
     461              def __del__(self):
     462                  try:
     463                      1/0
     464                  except:
     465                      raise
     466  
     467          def f():
     468              x = C()
     469              try:
     470                  try:
     471                      f.x
     472                  except AttributeError:
     473                      # make x.__del__ trigger
     474                      del x
     475                      gc.collect()  # For PyPy or other GCs.
     476                      raise TypeError
     477              except Exception as e:
     478                  self.assertNotEqual(e.__context__, None)
     479                  self.assertIsInstance(e.__context__, AttributeError)
     480  
     481          with support.catch_unraisable_exception() as cm:
     482              f()
     483  
     484              self.assertEqual(ZeroDivisionError, cm.unraisable.exc_type)
     485  
     486  
     487  class ESC[4;38;5;81mTestRemovedFunctionality(ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
     488      def test_tuples(self):
     489          try:
     490              raise (IndexError, KeyError) # This should be a tuple!
     491          except TypeError:
     492              pass
     493          else:
     494              self.fail("No exception raised")
     495  
     496      def test_strings(self):
     497          try:
     498              raise "foo"
     499          except TypeError:
     500              pass
     501          else:
     502              self.fail("No exception raised")
     503  
     504  
     505  if __name__ == "__main__":
     506      unittest.main()