https://github.com/python/cpython/commit/8c6f547f450877abc0f16abad710949aa672f9b8
commit: 8c6f547f450877abc0f16abad710949aa672f9b8
branch: 3.13
author: sobolevn <[email protected]>
committer: sobolevn <[email protected]>
date: 2026-06-26T15:03:05Z
summary:

[3.13] gh-152236: Fix skips on `_testcapi.set_nomemory` tests (GH-152253) 
(#152286)

* [3.13] gh-152236: Fix skips on `_testcapi.set_nomemory` tests (GH-152253)
(cherry picked from commit 1cbe460eb6c5f40980463f381b3096c92320ff84)

Co-authored-by: sobolevn <[email protected]>

files:
M Lib/test/support/__init__.py
M Lib/test/test_capi/test_mem.py
M Lib/test/test_class.py
M Lib/test/test_exceptions.py
M Lib/test/test_interpreters/test_stress.py
M Lib/test/test_repl.py
M Lib/test/test_weakref.py

diff --git a/Lib/test/support/__init__.py b/Lib/test/support/__init__.py
index 737ce94a120431d..6d8a1e786a4b5f7 100644
--- a/Lib/test/support/__init__.py
+++ b/Lib/test/support/__init__.py
@@ -34,7 +34,7 @@
     "requires_gil_enabled", "requires_linux_version", "requires_mac_ver",
     "check_syntax_error",
     "requires_gzip", "requires_bz2", "requires_lzma",
-    "bigmemtest", "bigaddrspacetest", "cpython_only", "get_attribute",
+    "bigmemtest", "nomemtest", "bigaddrspacetest", "cpython_only", 
"get_attribute",
     "requires_IEEE_754", "requires_zlib",
     "has_fork_support", "requires_fork",
     "has_subprocess_support", "requires_subprocess",
@@ -1215,6 +1215,22 @@ def wrapper(self):
         return wrapper
     return decorator
 
+def nomemtest(f):
+    """Check that we can use this test with `_testcapi.set_nomemory`."""
+    from .import_helper import import_module
+
+    @functools.wraps(f)
+    def internal(*args, **kwargs):
+        import_module('_testcapi')
+        return f(*args, **kwargs)
+
+    return unittest.skipIf(
+        # Python built with Py_TRACE_REFS fail with a fatal error in
+        # _PyRefchain_Trace() on memory allocation error.
+        Py_TRACE_REFS,
+        'cannot test Py_TRACE_REFS build',
+    )(cpython_only(internal))
+
 def bigaddrspacetest(f):
     """Decorator for tests that fill the address space."""
     def wrapper(self):
diff --git a/Lib/test/test_capi/test_mem.py b/Lib/test/test_capi/test_mem.py
index 6ab7b685c2e18bd..d67809956ac29da 100644
--- a/Lib/test/test_capi/test_mem.py
+++ b/Lib/test/test_capi/test_mem.py
@@ -112,9 +112,7 @@ def test_pyobject_forbidden_bytes_is_freed(self):
     def test_pyobject_freed_is_freed(self):
         self.check_pyobject_is_freed('check_pyobject_freed_is_freed')
 
-    # Python built with Py_TRACE_REFS fail with a fatal error in
-    # _PyRefchain_Trace() on memory allocation error.
-    @unittest.skipIf(support.Py_TRACE_REFS, 'cannot test Py_TRACE_REFS build')
+    @support.nomemtest
     def test_set_nomemory(self):
         code = """if 1:
             import _testcapi
diff --git a/Lib/test/test_class.py b/Lib/test/test_class.py
index 086aee9024c2e36..72e6d1676f594f6 100644
--- a/Lib/test/test_class.py
+++ b/Lib/test/test_class.py
@@ -1,6 +1,7 @@
 "Test the functionality of Python classes implementing operators."
 
 import unittest
+from test import support
 from test.support import cpython_only, import_helper, script_helper
 
 testmeths = [
@@ -447,7 +448,6 @@ def __delattr__(self, *args):
 
     def testHasAttrString(self):
         import sys
-        from test.support import import_helper
         _testlimitedcapi = import_helper.import_module('_testlimitedcapi')
 
         class A:
@@ -995,11 +995,8 @@ class C:
         C.a = X()
         C.a = X()
 
-    @cpython_only
+    @support.nomemtest
     def test_detach_materialized_dict_no_memory(self):
-        # Skip test if _testcapi is not available:
-        import_helper.import_module('_testcapi')
-
         code = """if 1:
             import test.support
             import _testcapi
diff --git a/Lib/test/test_exceptions.py b/Lib/test/test_exceptions.py
index ca1d2aa86bd0c81..c6a1cac2fe976fe 100644
--- a/Lib/test/test_exceptions.py
+++ b/Lib/test/test_exceptions.py
@@ -1531,11 +1531,7 @@ def recurse_in_body_and_except():
             sys.setrecursionlimit(recursionlimit)
 
 
-    @cpython_only
-    # Python built with Py_TRACE_REFS fail with a fatal error in
-    # _PyRefchain_Trace() on memory allocation error.
-    @unittest.skipIf(support.Py_TRACE_REFS, 'cannot test Py_TRACE_REFS build')
-    @unittest.skipIf(_testcapi is None, "requires _testcapi")
+    @support.nomemtest
     def test_recursion_normalizing_with_no_memory(self):
         # Issue #30697. Test that in the abort that occurs when there is no
         # memory left and the size of the Python frames stack is greater than
@@ -1719,11 +1715,7 @@ def test_unhandled(self):
                     self.assertIn("test message", report)
                 self.assertTrue(report.endswith("\n"))
 
-    @cpython_only
-    # Python built with Py_TRACE_REFS fail with a fatal error in
-    # _PyRefchain_Trace() on memory allocation error.
-    @unittest.skipIf(support.Py_TRACE_REFS, 'cannot test Py_TRACE_REFS build')
-    @unittest.skipIf(_testcapi is None, "requires _testcapi")
+    @support.nomemtest
     def test_memory_error_in_PyErr_PrintEx(self):
         code = """if 1:
             import _testcapi
@@ -1857,12 +1849,8 @@ def test_memory_error_in_subinterp(self):
         rc, _, err = script_helper.assert_python_ok("-c", code)
         self.assertIn(b'MemoryError', err)
 
-    @cpython_only
-    # Python built with Py_TRACE_REFS fail with a fatal error in
-    # _PyRefchain_Trace() on memory allocation error.
-    @unittest.skipIf(support.Py_TRACE_REFS, 'cannot test Py_TRACE_REFS build')
+    @support.nomemtest
     def test_exec_set_nomemory_hang(self):
-        import_module("_testcapi")
         # gh-134163: A MemoryError inside code that was wrapped by a try/except
         # block would lead to an infinite loop.
 
diff --git a/Lib/test/test_interpreters/test_stress.py 
b/Lib/test/test_interpreters/test_stress.py
index a39c9352f728d38..e3060cbd8bccd44 100644
--- a/Lib/test/test_interpreters/test_stress.py
+++ b/Lib/test/test_interpreters/test_stress.py
@@ -5,7 +5,7 @@
 from test.support import import_helper
 from test.support import threading_helper
 # Raise SkipTest if subinterpreters not supported.
-import_helper.import_module('_interpreters')
+_interpreters = import_helper.import_module('_interpreters')
 from test.support import interpreters
 from test.support.interpreters import InterpreterError
 from .utils import TestBase
@@ -75,9 +75,9 @@ def run():
             start.set()
         support.gc_collect()
 
+    @support.nomemtest
     def test_create_interpreter_no_memory(self):
-        import _interpreters
-        _testcapi = import_helper.import_module("_testcapi")
+        import _testcapi
 
         with self.assertRaises(InterpreterError):
             _testcapi.set_nomemory(0, 1)
diff --git a/Lib/test/test_repl.py b/Lib/test/test_repl.py
index 16109820beea744..9115e8cebabaca8 100644
--- a/Lib/test/test_repl.py
+++ b/Lib/test/test_repl.py
@@ -17,7 +17,6 @@
     SHORT_TIMEOUT,
 )
 from test.support.script_helper import kill_python
-from test.support.import_helper import import_module
 
 try:
     import pty
@@ -99,12 +98,8 @@ def run_on_interactive_mode(source):
 @support.force_not_colorized_test_class
 class TestInteractiveInterpreter(unittest.TestCase):
 
-    @cpython_only
-    # Python built with Py_TRACE_REFS fail with a fatal error in
-    # _PyRefchain_Trace() on memory allocation error.
-    @unittest.skipIf(support.Py_TRACE_REFS, 'cannot test Py_TRACE_REFS build')
+    @support.nomemtest
     def test_no_memory(self):
-        import_module("_testcapi")
         # Issue #30696: Fix the interactive interpreter looping endlessly when
         # no memory. Check also that the fix does not break the interactive
         # loop when an exception is raised.
diff --git a/Lib/test/test_weakref.py b/Lib/test/test_weakref.py
index 1a820d089d663df..d1523342ce10735 100644
--- a/Lib/test/test_weakref.py
+++ b/Lib/test/test_weakref.py
@@ -1022,7 +1022,7 @@ def __del__(self): pass
         del x
         support.gc_collect()
 
-    @support.cpython_only
+    @support.nomemtest
     def test_no_memory_when_clearing(self):
         # gh-118331: Make sure we do not raise an exception from the destructor
         # when clearing weakrefs if allocating the intermediate tuple fails.

_______________________________________________
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]

Reply via email to