Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 17 additions & 1 deletion Lib/test/support/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down Expand Up @@ -1226,6 +1226,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):
Expand Down
4 changes: 1 addition & 3 deletions Lib/test/test_atexit.py
Original file line number Diff line number Diff line change
Expand Up @@ -135,9 +135,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.
Expand Down
4 changes: 1 addition & 3 deletions Lib/test/test_capi/test_mem.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
6 changes: 1 addition & 5 deletions Lib/test/test_class.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -1012,11 +1011,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
Expand Down
18 changes: 3 additions & 15 deletions Lib/test/test_exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -1575,11 +1575,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
Expand Down Expand Up @@ -1766,11 +1762,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
Expand Down Expand Up @@ -1928,12 +1920,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.

Expand Down
11 changes: 6 additions & 5 deletions Lib/test/test_interpreters/test_stress.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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()


Expand Down
4 changes: 1 addition & 3 deletions Lib/test/test_list.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
7 changes: 1 addition & 6 deletions Lib/test/test_repl.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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.
Expand Down
2 changes: 1 addition & 1 deletion Lib/test/test_weakref.py
Original file line number Diff line number Diff line change
Expand Up @@ -1019,7 +1019,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.
Expand Down
Loading