[3.13] gh-155146: Do not depend on the exact number of allocations in test_class (GH-155150) (GH-155157)

serhiy-storchaka <[email protected]> Tue, 04 Aug 2026 05:14:18 -0400 (EDT)
Newsgroups gmane.comp.python.cvs
Message-ID <[email protected]>
https://github.com/python/cpython/commit/42b23dad80e81b264487fd400217cab465ff70b9
commit: 42b23dad80e81b264487fd400217cab465ff70b9
branch: 3.13
author: Miss Islington (bot) <[email protected]>
committer: serhiy-storchaka <[email protected]>
date: 2026-08-04T09:14:04Z
summary:

[3.13] gh-155146: Do not depend on the exact number of allocations in test_class (GH-155150) (GH-155157)

Try to fail every one of the first allocations and accept the first one which
fails in the code detaching the instance dictionary from the object, instead
of assuming that this is the first allocation after set_nomemory().

Run the test with the test.support.isolation.runInSubprocess() decorator
instead of executing it as a source string in a subprocess.
(cherry picked from commit 416c3465e247bc5a36f86b832360f65e06a0767a)

Co-authored-by: Serhiy Storchaka <[email protected]>
Co-authored-by: Claude Opus 5 (1M context) <[email protected]>

files:
M Lib/test/test_class.py

diff --git a/Lib/test/test_class.py b/Lib/test/test_class.py
index 72e6d1676f594f..feca8844ad57e2 100644
--- a/Lib/test/test_class.py
+++ b/Lib/test/test_class.py
@@ -2,7 +2,7 @@
 
 import unittest
 from test import support
-from test.support import cpython_only, import_helper, script_helper
+from test.support import cpython_only, import_helper, isolation
 
 testmeths = [
 
@@ -996,32 +996,43 @@ class C:
         C.a = X()
 
     @support.nomemtest
+    @isolation.runInSubprocess()
     def test_detach_materialized_dict_no_memory(self):
-        code = """if 1:
-            import test.support
-            import _testcapi
-
-            class A:
-                def __init__(self):
-                    self.a = 1
-                    self.b = 2
+        import _testcapi
+
+        class A:
+            def __init__(self):
+                self.a = 1
+                self.b = 2
+
+        # The failing allocation should be the one which detaches the
+        # dictionary from the object, but other allocations can happen
+        # first, so try to fail every one of the first allocations.
+        raised = False
+        for n in range(20):
             a = A()
             d = a.__dict__
-            with test.support.catch_unraisable_exception() as ex:
-                _testcapi.set_nomemory(0, 1)
-                del a
-                assert ex.unraisable.exc_type is MemoryError
             try:
-                d["a"]
-            except KeyError:
-                pass
-            else:
-                assert False, "KeyError not raised"
-        """
-        rc, out, err = script_helper.assert_python_ok("-c", code)
-        self.assertEqual(rc, 0)
-        self.assertFalse(out, msg=out.decode('utf-8'))
-        self.assertFalse(err, msg=err.decode('utf-8'))
+                with support.catch_unraisable_exception() as ex:
+                    _testcapi.set_nomemory(n, n + 1)
+                    try:
+                        del a
+                    finally:
+                        _testcapi.remove_mem_hooks()
+                    exc_type = ex.unraisable and ex.unraisable.exc_type
+            except MemoryError:
+                # The failing allocation was not in the deallocation code.
+                continue
+            if exc_type is not MemoryError:
+                continue
+            raised = True
+            if "a" not in d:
+                # The dictionary was cleared, as expected.
+                break
+        else:
+            if not raised:
+                self.fail("MemoryError was not raised during deallocation")
+            self.fail("the dictionary was not cleared")
 
 if __name__ == '__main__':
     unittest.main()

_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3//lists/python-checkins.python.org
Member address: [email protected]