]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
[3.13] gh-152236: Fix skips on `_testcapi.set_nomemory` tests (GH-152253) (#152286)
authorsobolevn <mail@sobolevn.me>
Fri, 26 Jun 2026 15:03:05 +0000 (18:03 +0300)
committerGitHub <noreply@github.com>
Fri, 26 Jun 2026 15:03:05 +0000 (15:03 +0000)
* [3.13] gh-152236: Fix skips on `_testcapi.set_nomemory` tests (GH-152253)
(cherry picked from commit 1cbe460eb6c5f40980463f381b3096c92320ff84)

Co-authored-by: sobolevn <mail@sobolevn.me>
Lib/test/support/__init__.py
Lib/test/test_capi/test_mem.py
Lib/test/test_class.py
Lib/test/test_exceptions.py
Lib/test/test_interpreters/test_stress.py
Lib/test/test_repl.py
Lib/test/test_weakref.py

index 737ce94a120431dfe7c76acb6dd8960b744fa47f..6d8a1e786a4b5f73df8f1dc55b3a79b441ed8c5d 100644 (file)
@@ -34,7 +34,7 @@ __all__ = [
     "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 bigmemtest(size, memuse, dry_run=True):
         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):
index 6ab7b685c2e18bd04e1f8e4251a25db9f0249245..d67809956ac29da805759d450d96c6bb254a2e2f 100644 (file)
@@ -112,9 +112,7 @@ class PyMemDebugTests(unittest.TestCase):
     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
index 086aee9024c2e36c774306465fb51a8e4defdf88..72e6d1676f594f6e7c1481074807fc763e554cf9 100644 (file)
@@ -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 @@ class ClassTests(unittest.TestCase):
 
     def testHasAttrString(self):
         import sys
-        from test.support import import_helper
         _testlimitedcapi = import_helper.import_module('_testlimitedcapi')
 
         class A:
@@ -995,11 +995,8 @@ class TestInlineValues(unittest.TestCase):
         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
index ca1d2aa86bd0c81dae3a5dd5e8385e6bfcc323ad..c6a1cac2fe976fe1f8d951bb253fe563888f5ce0 100644 (file)
@@ -1531,11 +1531,7 @@ class ExceptionTests(unittest.TestCase):
             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 @@ class ExceptionTests(unittest.TestCase):
                     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 @@ class ExceptionTests(unittest.TestCase):
         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.
 
index a39c9352f728d38265dab8c4a13b1fb5f801e078..e3060cbd8bccd44e9df732abe17f9e3ad2ef86d8 100644 (file)
@@ -5,7 +5,7 @@ from test import support
 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 @@ class StressTests(TestBase):
             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)
index 16109820beea74412e1a34d99915210bd433fc61..9115e8cebabaca86cc2218234071ee658ced4310 100644 (file)
@@ -17,7 +17,6 @@ from test.support import (
     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.
index 1a820d089d663dfb5f25142d9535279dec271c2c..d1523342ce10735f3e48898d762097ebab55c62c 100644 (file)
@@ -1022,7 +1022,7 @@ class ReferencesTestCase(TestBase):
         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.