(self)
| 721 | @requires_subprocess() |
| 722 | @unittest.skipIf(_testcapi is None, "requires _testcapi") |
| 723 | def test_garbage_at_shutdown(self): |
| 724 | import subprocess |
| 725 | code = """if 1: |
| 726 | import gc |
| 727 | import _testcapi |
| 728 | @_testcapi.with_tp_del |
| 729 | class X: |
| 730 | def __init__(self, name): |
| 731 | self.name = name |
| 732 | def __repr__(self): |
| 733 | return "<X %%r>" %% self.name |
| 734 | def __tp_del__(self): |
| 735 | pass |
| 736 | |
| 737 | x = X('first') |
| 738 | x.x = x |
| 739 | x.y = X('second') |
| 740 | del x |
| 741 | gc.set_debug(%s) |
| 742 | """ |
| 743 | def run_command(code): |
| 744 | p = subprocess.Popen([sys.executable, "-Wd", "-c", code], |
| 745 | stdout=subprocess.PIPE, |
| 746 | stderr=subprocess.PIPE) |
| 747 | stdout, stderr = p.communicate() |
| 748 | p.stdout.close() |
| 749 | p.stderr.close() |
| 750 | self.assertEqual(p.returncode, 0) |
| 751 | self.assertEqual(stdout, b"") |
| 752 | return stderr |
| 753 | |
| 754 | stderr = run_command(code % "0") |
| 755 | self.assertIn(b"ResourceWarning: gc: 2 uncollectable objects at " |
| 756 | b"shutdown; use", stderr) |
| 757 | self.assertNotIn(b"<X 'first'>", stderr) |
| 758 | one_line_re = b"gc: uncollectable <X 0x[0-9A-Fa-f]+>" |
| 759 | expected_re = one_line_re + b"\r?\n" + one_line_re |
| 760 | self.assertNotRegex(stderr, expected_re) |
| 761 | # With DEBUG_UNCOLLECTABLE, the garbage list gets printed |
| 762 | stderr = run_command(code % "gc.DEBUG_UNCOLLECTABLE") |
| 763 | self.assertIn(b"ResourceWarning: gc: 2 uncollectable objects at " |
| 764 | b"shutdown", stderr) |
| 765 | self.assertTrue( |
| 766 | (b"[<X 'first'>, <X 'second'>]" in stderr) or |
| 767 | (b"[<X 'second'>, <X 'first'>]" in stderr), stderr) |
| 768 | # we expect two lines with uncollectable objects |
| 769 | self.assertRegex(stderr, expected_re) |
| 770 | # With DEBUG_SAVEALL, no additional message should get printed |
| 771 | # (because gc.garbage also contains normally reclaimable cyclic |
| 772 | # references, and its elements get printed at runtime anyway). |
| 773 | stderr = run_command(code % "gc.DEBUG_SAVEALL") |
| 774 | self.assertNotIn(b"uncollectable objects at shutdown", stderr) |
| 775 | |
| 776 | def test_gc_main_module_at_shutdown(self): |
| 777 | # Create a reference cycle through the __main__ module and check |
nothing calls this directly
no test coverage detected