https://github.com/python/cpython/commit/aaeca91b05fdc781dc97a51e53b368b1edb14fb8
commit: aaeca91b05fdc781dc97a51e53b368b1edb14fb8
branch: 3.14
author: Miss Islington (bot) <31488909+miss-isling...@users.noreply.github.com>
committer: nascheme <nas-git...@arctrix.com>
date: 2025-05-09T12:30:27-07:00
summary:

[3.14] gh-133532: Run GC fast cycles test in subprocess. (gh-133533) (gh-133716)

This makes the test more reliable since there are not extra objects on the heap 
leftover
from other tests.

(cherry picked from commit 8598e57942f26ca1feecc0aefb421935e4e9f2aa)

Co-authored-by: Neil Schemenauer <nas-git...@arctrix.com>

files:
A Lib/test/_test_gc_fast_cycles.py
M Lib/test/test_gc.py

diff --git a/Lib/test/_test_gc_fast_cycles.py b/Lib/test/_test_gc_fast_cycles.py
new file mode 100644
index 00000000000000..4e2c7d72a02713
--- /dev/null
+++ b/Lib/test/_test_gc_fast_cycles.py
@@ -0,0 +1,48 @@
+# Run by test_gc.
+from test import support
+import _testinternalcapi
+import gc
+import unittest
+
+class IncrementalGCTests(unittest.TestCase):
+
+    # Use small increments to emulate longer running process in a shorter time
+    @support.gc_threshold(200, 10)
+    def test_incremental_gc_handles_fast_cycle_creation(self):
+
+        class LinkedList:
+
+            #Use slots to reduce number of implicit objects
+            __slots__ = "next", "prev", "surprise"
+
+            def __init__(self, next=None, prev=None):
+                self.next = next
+                if next is not None:
+                    next.prev = self
+                self.prev = prev
+                if prev is not None:
+                    prev.next = self
+
+        def make_ll(depth):
+            head = LinkedList()
+            for i in range(depth):
+                head = LinkedList(head, head.prev)
+            return head
+
+        head = make_ll(1000)
+
+        assert(gc.isenabled())
+        olds = []
+        initial_heap_size = _testinternalcapi.get_tracked_heap_size()
+        for i in range(20_000):
+            newhead = make_ll(20)
+            newhead.surprise = head
+            olds.append(newhead)
+            if len(olds) == 20:
+                new_objects = _testinternalcapi.get_tracked_heap_size() - 
initial_heap_size
+                self.assertLess(new_objects, 27_000, f"Heap growing. Reached 
limit after {i} iterations")
+                del olds[:]
+
+
+if __name__ == "__main__":
+    unittest.main()
diff --git a/Lib/test/test_gc.py b/Lib/test/test_gc.py
index 8fae12c478cb3a..95c98c6ac63f71 100644
--- a/Lib/test/test_gc.py
+++ b/Lib/test/test_gc.py
@@ -7,7 +7,7 @@
                           Py_GIL_DISABLED)
 from test.support.import_helper import import_module
 from test.support.os_helper import temp_dir, TESTFN, unlink
-from test.support.script_helper import assert_python_ok, make_script
+from test.support.script_helper import assert_python_ok, make_script, 
run_test_script
 from test.support import threading_helper, gc_threshold
 
 import gc
@@ -1127,64 +1127,14 @@ def test_something(self):
 
 
 class IncrementalGCTests(unittest.TestCase):
-
-    def setUp(self):
-        # Reenable GC as it is disabled module-wide
-        gc.enable()
-
-    def tearDown(self):
-        gc.disable()
-
     @unittest.skipIf(_testinternalcapi is None, "requires _testinternalcapi")
     @requires_gil_enabled("Free threading does not support incremental GC")
-    # Use small increments to emulate longer running process in a shorter time
-    @gc_threshold(200, 10)
     def test_incremental_gc_handles_fast_cycle_creation(self):
-
-        class LinkedList:
-
-            #Use slots to reduce number of implicit objects
-            __slots__ = "next", "prev", "surprise"
-
-            def __init__(self, next=None, prev=None):
-                self.next = next
-                if next is not None:
-                    next.prev = self
-                self.prev = prev
-                if prev is not None:
-                    prev.next = self
-
-        def make_ll(depth):
-            head = LinkedList()
-            for i in range(depth):
-                head = LinkedList(head, head.prev)
-            return head
-
-        head = make_ll(1000)
-        count = 1000
-
-        # There will be some objects we aren't counting,
-        # e.g. the gc stats dicts. This test checks
-        # that the counts don't grow, so we try to
-        # correct for the uncounted objects
-        # This is just an estimate.
-        CORRECTION = 20
-
-        enabled = gc.isenabled()
-        gc.enable()
-        olds = []
-        initial_heap_size = _testinternalcapi.get_tracked_heap_size()
-        for i in range(20_000):
-            newhead = make_ll(20)
-            count += 20
-            newhead.surprise = head
-            olds.append(newhead)
-            if len(olds) == 20:
-                new_objects = _testinternalcapi.get_tracked_heap_size() - 
initial_heap_size
-                self.assertLess(new_objects, 27_000, f"Heap growing. Reached 
limit after {i} iterations")
-                del olds[:]
-        if not enabled:
-            gc.disable()
+        # Run this test in a fresh process.  The number of alive objects 
(which can
+        # be from unit tests run before this one) can influence how quickly 
cyclic
+        # garbage is found.
+        script = support.findfile("_test_gc_fast_cycles.py")
+        run_test_script(script)
 
 
 class GCCallbackTests(unittest.TestCase):

_______________________________________________
Python-checkins mailing list -- python-checkins@python.org
To unsubscribe send an email to python-checkins-le...@python.org
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: arch...@mail-archive.com

Reply via email to