https://github.com/python/cpython/commit/1cbe460eb6c5f40980463f381b3096c92320ff84
commit: 1cbe460eb6c5f40980463f381b3096c92320ff84
branch: main
author: sobolevn <[email protected]>
committer: sobolevn <[email protected]>
date: 2026-06-26T13:36:41Z
summary:
gh-152236: Fix skips on `_testcapi.set_nomemory` tests (#152253)
files:
M Lib/test/support/__init__.py
M Lib/test/test_atexit.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_list.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 e9966e1f7a6d495..a3f8a733a081f62 100644
--- a/Lib/test/support/__init__.py
+++ b/Lib/test/support/__init__.py
@@ -35,7 +35,7 @@
"requires_gil_enabled", "requires_linux_version", "requires_mac_ver",
"check_syntax_error",
"requires_gzip", "requires_bz2", "requires_lzma", "requires_zstd",
- "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",
@@ -1305,6 +1305,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_atexit.py b/Lib/test/test_atexit.py
index 8256ff183f28c9c..33c37648da31fc7 100644
--- a/Lib/test/test_atexit.py
+++ b/Lib/test/test_atexit.py
@@ -191,9 +191,7 @@ def callback():
self.assertEqual(os.read(r, len(expected)), expected)
os.close(r)
- # 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_atexit_with_low_memory(self):
# gh-140080: Test that setting low memory after registering an atexit
# callback doesn't cause an infinite loop during finalization.
diff --git a/Lib/test/test_capi/test_mem.py b/Lib/test/test_capi/test_mem.py
index 5035b2b4829bf64..66ab072733e17bd 100644
--- a/Lib/test/test_capi/test_mem.py
+++ b/Lib/test/test_capi/test_mem.py
@@ -117,9 +117,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 64222555166a2e3..e401941c6d69700 100644
--- a/Lib/test/test_class.py
+++ b/Lib/test/test_class.py
@@ -449,7 +449,6 @@ def __delattr__(self, *args):
def testHasAttrString(self):
import sys
- from test.support import import_helper
_testlimitedcapi = import_helper.import_module('_testlimitedcapi')
class A:
@@ -1013,11 +1012,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 df7a04273b9b41c..cc7faef93e1af7c 100644
--- a/Lib/test/test_exceptions.py
+++ b/Lib/test/test_exceptions.py
@@ -1583,11 +1583,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
@@ -1774,11 +1770,7 @@ def test_unhandled(self):
self.assertIn("test message", report)
self.assertEndsWith(report, "\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
@@ -1936,12 +1928,8 @@ def test_keyerror_context(self):
exc2 = None
- @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 6b40a536bd3c319..50d87a6ccd3cadb 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 concurrent import interpreters
from concurrent.interpreters import InterpreterError
from .utils import TestBase
@@ -75,12 +75,13 @@ 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)
+ assertion = self.assertRaises(InterpreterError)
+ _testcapi.set_nomemory(0, 1)
+ with assertion:
_interpreters.create()
diff --git a/Lib/test/test_list.py b/Lib/test/test_list.py
index 642b54d34849dab..44ecd62d6735def 100644
--- a/Lib/test/test_list.py
+++ b/Lib/test/test_list.py
@@ -3,7 +3,6 @@
import textwrap
from test import list_tests, support
from test.support import cpython_only
-from test.support.import_helper import import_module
from test.support.script_helper import assert_python_failure, assert_python_ok
import pickle
import unittest
@@ -326,10 +325,9 @@ def test_tier2_invalidates_iterator(self):
a.append(4)
self.assertEqual(list(it), [])
- @support.cpython_only
+ @support.nomemtest
def test_no_memory(self):
# gh-118331: Make sure we don't crash if list allocation fails
- import_module("_testcapi")
code = textwrap.dedent("""
import _testcapi, sys
# Prime the freelist
diff --git a/Lib/test/test_repl.py b/Lib/test/test_repl.py
index 850cb66a89ba84a..0f5009c32124902 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 0c4717521f16f67..b9d1745592c09ca 100644
--- a/Lib/test/test_weakref.py
+++ b/Lib/test/test_weakref.py
@@ -1024,7 +1024,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]