(root)/
Python-3.12.0/
Lib/
test/
test_atexit.py
       1  import atexit
       2  import os
       3  import textwrap
       4  import unittest
       5  from test import support
       6  from test.support import script_helper
       7  
       8  
       9  class ESC[4;38;5;81mGeneralTest(ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
      10      def test_general(self):
      11          # Run _test_atexit.py in a subprocess since it calls atexit._clear()
      12          script = support.findfile("_test_atexit.py")
      13          script_helper.run_test_script(script)
      14  
      15  class ESC[4;38;5;81mFunctionalTest(ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
      16      def test_shutdown(self):
      17          # Actually test the shutdown mechanism in a subprocess
      18          code = textwrap.dedent("""
      19              import atexit
      20  
      21              def f(msg):
      22                  print(msg)
      23  
      24              atexit.register(f, "one")
      25              atexit.register(f, "two")
      26          """)
      27          res = script_helper.assert_python_ok("-c", code)
      28          self.assertEqual(res.out.decode().splitlines(), ["two", "one"])
      29          self.assertFalse(res.err)
      30  
      31      def test_atexit_instances(self):
      32          # bpo-42639: It is safe to have more than one atexit instance.
      33          code = textwrap.dedent("""
      34              import sys
      35              import atexit as atexit1
      36              del sys.modules['atexit']
      37              import atexit as atexit2
      38              del sys.modules['atexit']
      39  
      40              assert atexit2 is not atexit1
      41  
      42              atexit1.register(print, "atexit1")
      43              atexit2.register(print, "atexit2")
      44          """)
      45          res = script_helper.assert_python_ok("-c", code)
      46          self.assertEqual(res.out.decode().splitlines(), ["atexit2", "atexit1"])
      47          self.assertFalse(res.err)
      48  
      49  
      50  @support.cpython_only
      51  class ESC[4;38;5;81mSubinterpreterTest(ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
      52  
      53      def test_callbacks_leak(self):
      54          # This test shows a leak in refleak mode if atexit doesn't
      55          # take care to free callbacks in its per-subinterpreter module
      56          # state.
      57          n = atexit._ncallbacks()
      58          code = textwrap.dedent(r"""
      59              import atexit
      60              def f():
      61                  pass
      62              atexit.register(f)
      63              del atexit
      64          """)
      65          ret = support.run_in_subinterp(code)
      66          self.assertEqual(ret, 0)
      67          self.assertEqual(atexit._ncallbacks(), n)
      68  
      69      def test_callbacks_leak_refcycle(self):
      70          # Similar to the above, but with a refcycle through the atexit
      71          # module.
      72          n = atexit._ncallbacks()
      73          code = textwrap.dedent(r"""
      74              import atexit
      75              def f():
      76                  pass
      77              atexit.register(f)
      78              atexit.__atexit = atexit
      79          """)
      80          ret = support.run_in_subinterp(code)
      81          self.assertEqual(ret, 0)
      82          self.assertEqual(atexit._ncallbacks(), n)
      83  
      84      @unittest.skipUnless(hasattr(os, "pipe"), "requires os.pipe()")
      85      def test_callback_on_subinterpreter_teardown(self):
      86          # This tests if a callback is called on
      87          # subinterpreter teardown.
      88          expected = b"The test has passed!"
      89          r, w = os.pipe()
      90  
      91          code = textwrap.dedent(r"""
      92              import os
      93              import atexit
      94              def callback():
      95                  os.write({:d}, b"The test has passed!")
      96              atexit.register(callback)
      97          """.format(w))
      98          ret = support.run_in_subinterp(code)
      99          os.close(w)
     100          self.assertEqual(os.read(r, len(expected)), expected)
     101          os.close(r)
     102  
     103  
     104  if __name__ == "__main__":
     105      unittest.main()