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