summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorErlend E. Aasland <erlend@python.org>2024-04-08 12:45:25 (GMT)
committerGitHub <noreply@github.com>2024-04-08 12:45:25 (GMT)
commitca62ffd1a5ef41401abceddfd171c76c68825a35 (patch)
treebc5ece1694f0d99642446844f74be11ebd7e53b0
parent9a12f5d1c19dee1f89684be776680aeaf117be5b (diff)
downloadcpython-ca62ffd1a5ef41401abceddfd171c76c68825a35.zip
cpython-ca62ffd1a5ef41401abceddfd171c76c68825a35.tar.gz
cpython-ca62ffd1a5ef41401abceddfd171c76c68825a35.tar.bz2
gh-116303: Skip tests if C recursion limit is unavailable (GH-117368)
The test suite fetches the C recursion limit from the _testcapi extension module. Test extension modules can be disabled using the --disable-test-modules configure option.
-rw-r--r--Lib/test/list_tests.py4
-rw-r--r--Lib/test/mapping_tests.py4
-rw-r--r--Lib/test/support/__init__.py20
-rw-r--r--Lib/test/test_ast.py4
-rw-r--r--Lib/test/test_collections.py2
-rw-r--r--Lib/test/test_compile.py11
-rw-r--r--Lib/test/test_dict.py4
-rw-r--r--Lib/test/test_dictviews.py4
-rw-r--r--Lib/test/test_exception_group.py4
-rw-r--r--Lib/test/test_exceptions.py2
-rw-r--r--Lib/test/test_functools.py2
-rw-r--r--Lib/test/test_isinstance.py2
-rw-r--r--Lib/test/test_marshal.py2
-rw-r--r--Lib/test/test_sys_settrace.py2
14 files changed, 32 insertions, 35 deletions
diff --git a/Lib/test/list_tests.py b/Lib/test/list_tests.py
index 26118e1..89cd10f 100644
--- a/Lib/test/list_tests.py
+++ b/Lib/test/list_tests.py
@@ -6,7 +6,7 @@ import sys
from functools import cmp_to_key
from test import seq_tests
-from test.support import ALWAYS_EQ, NEVER_EQ, Py_C_RECURSION_LIMIT
+from test.support import ALWAYS_EQ, NEVER_EQ, get_c_recursion_limit
class CommonTest(seq_tests.CommonTest):
@@ -61,7 +61,7 @@ class CommonTest(seq_tests.CommonTest):
def test_repr_deep(self):
a = self.type2test([])
- for i in range(Py_C_RECURSION_LIMIT + 1):
+ for i in range(get_c_recursion_limit() + 1):
a = self.type2test([a])
self.assertRaises(RecursionError, repr, a)
diff --git a/Lib/test/mapping_tests.py b/Lib/test/mapping_tests.py
index b4cfce1..ed89a81 100644
--- a/Lib/test/mapping_tests.py
+++ b/Lib/test/mapping_tests.py
@@ -1,7 +1,7 @@
# tests common to dict and UserDict
import unittest
import collections
-from test.support import Py_C_RECURSION_LIMIT
+from test.support import get_c_recursion_limit
class BasicTestMappingProtocol(unittest.TestCase):
@@ -624,7 +624,7 @@ class TestHashMappingProtocol(TestMappingProtocol):
def test_repr_deep(self):
d = self._empty_mapping()
- for i in range(Py_C_RECURSION_LIMIT + 1):
+ for i in range(get_c_recursion_limit() + 1):
d0 = d
d = self._empty_mapping()
d[1] = d0
diff --git a/Lib/test/support/__init__.py b/Lib/test/support/__init__.py
index 2be9cd0..4bf2d7b 100644
--- a/Lib/test/support/__init__.py
+++ b/Lib/test/support/__init__.py
@@ -56,7 +56,7 @@ __all__ = [
"run_with_tz", "PGO", "missing_compiler_executable",
"ALWAYS_EQ", "NEVER_EQ", "LARGEST", "SMALLEST",
"LOOPBACK_TIMEOUT", "INTERNET_TIMEOUT", "SHORT_TIMEOUT", "LONG_TIMEOUT",
- "Py_DEBUG", "EXCEEDS_RECURSION_LIMIT", "Py_C_RECURSION_LIMIT",
+ "Py_DEBUG", "exceeds_recursion_limit", "get_c_recursion_limit",
"skip_on_s390x",
"without_optimizer",
]
@@ -2490,22 +2490,18 @@ def adjust_int_max_str_digits(max_digits):
sys.set_int_max_str_digits(current)
-def _get_c_recursion_limit():
+def get_c_recursion_limit():
try:
import _testcapi
return _testcapi.Py_C_RECURSION_LIMIT
- except (ImportError, AttributeError):
- # Originally taken from Include/cpython/pystate.h .
- if sys.platform == 'win32':
- return 4000
- else:
- return 10000
+ except ImportError:
+ raise unittest.SkipTest('requires _testcapi')
+
-# The default C recursion limit.
-Py_C_RECURSION_LIMIT = _get_c_recursion_limit()
+def exceeds_recursion_limit():
+ """For recursion tests, easily exceeds default recursion limit."""
+ return get_c_recursion_limit() * 3
-#For recursion tests, easily exceeds default recursion limit
-EXCEEDS_RECURSION_LIMIT = Py_C_RECURSION_LIMIT * 3
#Windows doesn't have os.uname() but it doesn't support s390x.
skip_on_s390x = unittest.skipIf(hasattr(os, 'uname') and os.uname().machine == 's390x',
diff --git a/Lib/test/test_ast.py b/Lib/test/test_ast.py
index 3929e4e..5b47cda 100644
--- a/Lib/test/test_ast.py
+++ b/Lib/test/test_ast.py
@@ -1153,9 +1153,9 @@ class AST_Tests(unittest.TestCase):
@support.cpython_only
def test_ast_recursion_limit(self):
- fail_depth = support.EXCEEDS_RECURSION_LIMIT
+ fail_depth = support.exceeds_recursion_limit()
crash_depth = 100_000
- success_depth = int(support.Py_C_RECURSION_LIMIT * 0.8)
+ success_depth = int(support.get_c_recursion_limit() * 0.8)
if _testinternalcapi is not None:
remaining = _testinternalcapi.get_c_recursion_remaining()
success_depth = min(success_depth, remaining)
diff --git a/Lib/test/test_collections.py b/Lib/test/test_collections.py
index 1fb492e..955323c 100644
--- a/Lib/test/test_collections.py
+++ b/Lib/test/test_collections.py
@@ -542,7 +542,7 @@ class TestNamedTuple(unittest.TestCase):
self.assertEqual(Dot(1)._replace(d=999), (999,))
self.assertEqual(Dot(1)._fields, ('d',))
- n = support.EXCEEDS_RECURSION_LIMIT
+ n = support.exceeds_recursion_limit()
names = list(set(''.join([choice(string.ascii_letters)
for j in range(10)]) for i in range(n)))
n = len(names)
diff --git a/Lib/test/test_compile.py b/Lib/test/test_compile.py
index 9d5f721..638b6e9 100644
--- a/Lib/test/test_compile.py
+++ b/Lib/test/test_compile.py
@@ -13,7 +13,7 @@ import textwrap
import warnings
from test import support
from test.support import (script_helper, requires_debug_ranges,
- requires_specialization, Py_C_RECURSION_LIMIT)
+ requires_specialization, get_c_recursion_limit)
from test.support.bytecode_helper import instructions_with_positions
from test.support.os_helper import FakePath
@@ -114,7 +114,7 @@ class TestSpecifics(unittest.TestCase):
@unittest.skipIf(support.is_wasi, "exhausts limited stack on WASI")
def test_extended_arg(self):
- repeat = int(Py_C_RECURSION_LIMIT * 0.9)
+ repeat = int(get_c_recursion_limit() * 0.9)
longexpr = 'x = x or ' + '-x' * repeat
g = {}
code = textwrap.dedent('''
@@ -634,9 +634,10 @@ class TestSpecifics(unittest.TestCase):
@unittest.skipIf(support.is_wasi, "exhausts limited stack on WASI")
def test_compiler_recursion_limit(self):
# Expected limit is Py_C_RECURSION_LIMIT
- fail_depth = Py_C_RECURSION_LIMIT + 1
- crash_depth = Py_C_RECURSION_LIMIT * 100
- success_depth = int(Py_C_RECURSION_LIMIT * 0.8)
+ limit = get_c_recursion_limit()
+ fail_depth = limit + 1
+ crash_depth = limit * 100
+ success_depth = int(limit * 0.8)
def check_limit(prefix, repeated, mode="single"):
expect_ok = prefix + repeated * success_depth
diff --git a/Lib/test/test_dict.py b/Lib/test/test_dict.py
index 620d0ca..e5dba7c 100644
--- a/Lib/test/test_dict.py
+++ b/Lib/test/test_dict.py
@@ -8,7 +8,7 @@ import sys
import unittest
import weakref
from test import support
-from test.support import import_helper, Py_C_RECURSION_LIMIT
+from test.support import import_helper, get_c_recursion_limit
class DictTest(unittest.TestCase):
@@ -596,7 +596,7 @@ class DictTest(unittest.TestCase):
def test_repr_deep(self):
d = {}
- for i in range(Py_C_RECURSION_LIMIT + 1):
+ for i in range(get_c_recursion_limit() + 1):
d = {1: d}
self.assertRaises(RecursionError, repr, d)
diff --git a/Lib/test/test_dictviews.py b/Lib/test/test_dictviews.py
index cad568b..d988161 100644
--- a/Lib/test/test_dictviews.py
+++ b/Lib/test/test_dictviews.py
@@ -2,7 +2,7 @@ import collections.abc
import copy
import pickle
import unittest
-from test.support import Py_C_RECURSION_LIMIT
+from test.support import get_c_recursion_limit
class DictSetTest(unittest.TestCase):
@@ -279,7 +279,7 @@ class DictSetTest(unittest.TestCase):
def test_deeply_nested_repr(self):
d = {}
- for i in range(Py_C_RECURSION_LIMIT//2 + 100):
+ for i in range(get_c_recursion_limit()//2 + 100):
d = {42: d.values()}
self.assertRaises(RecursionError, repr, d)
diff --git a/Lib/test/test_exception_group.py b/Lib/test/test_exception_group.py
index 2012267..b4fc290 100644
--- a/Lib/test/test_exception_group.py
+++ b/Lib/test/test_exception_group.py
@@ -1,7 +1,7 @@
import collections.abc
import types
import unittest
-from test.support import Py_C_RECURSION_LIMIT
+from test.support import get_c_recursion_limit
class TestExceptionGroupTypeHierarchy(unittest.TestCase):
def test_exception_group_types(self):
@@ -460,7 +460,7 @@ class ExceptionGroupSplitTests(ExceptionGroupTestBase):
class DeepRecursionInSplitAndSubgroup(unittest.TestCase):
def make_deep_eg(self):
e = TypeError(1)
- for i in range(Py_C_RECURSION_LIMIT + 1):
+ for i in range(get_c_recursion_limit() + 1):
e = ExceptionGroup('eg', [e])
return e
diff --git a/Lib/test/test_exceptions.py b/Lib/test/test_exceptions.py
index 6ad6acc..36fd89d 100644
--- a/Lib/test/test_exceptions.py
+++ b/Lib/test/test_exceptions.py
@@ -1424,7 +1424,7 @@ class ExceptionTests(unittest.TestCase):
next(generator)
recursionlimit = sys.getrecursionlimit()
try:
- recurse(support.EXCEEDS_RECURSION_LIMIT)
+ recurse(support.exceeds_recursion_limit())
finally:
sys.setrecursionlimit(recursionlimit)
print('Done.')
diff --git a/Lib/test/test_functools.py b/Lib/test/test_functools.py
index 3ba4929..c48c399 100644
--- a/Lib/test/test_functools.py
+++ b/Lib/test/test_functools.py
@@ -1867,7 +1867,7 @@ class TestLRU:
return fib(n-1) + fib(n-2)
if not support.Py_DEBUG:
- depth = support.Py_C_RECURSION_LIMIT*2//7
+ depth = support.get_c_recursion_limit()*2//7
with support.infinite_recursion():
fib(depth)
if self.module == c_functools:
diff --git a/Lib/test/test_isinstance.py b/Lib/test/test_isinstance.py
index 7f759fb..95a119b 100644
--- a/Lib/test/test_isinstance.py
+++ b/Lib/test/test_isinstance.py
@@ -352,7 +352,7 @@ def blowstack(fxn, arg, compare_to):
# Make sure that calling isinstance with a deeply nested tuple for its
# argument will raise RecursionError eventually.
tuple_arg = (compare_to,)
- for cnt in range(support.EXCEEDS_RECURSION_LIMIT):
+ for cnt in range(support.exceeds_recursion_limit()):
tuple_arg = (tuple_arg,)
fxn(arg, tuple_arg)
diff --git a/Lib/test/test_marshal.py b/Lib/test/test_marshal.py
index 615568e..64ee1ba 100644
--- a/Lib/test/test_marshal.py
+++ b/Lib/test/test_marshal.py
@@ -118,7 +118,7 @@ class CodeTestCase(unittest.TestCase):
def test_many_codeobjects(self):
# Issue2957: bad recursion count on code objects
# more than MAX_MARSHAL_STACK_DEPTH
- count = support.EXCEEDS_RECURSION_LIMIT
+ count = support.exceeds_recursion_limit()
codes = (ExceptionTestCase.test_exceptions.__code__,) * count
marshal.loads(marshal.dumps(codes))
diff --git a/Lib/test/test_sys_settrace.py b/Lib/test/test_sys_settrace.py
index 125f402..ded1d92 100644
--- a/Lib/test/test_sys_settrace.py
+++ b/Lib/test/test_sys_settrace.py
@@ -3039,7 +3039,7 @@ class TestExtendedArgs(unittest.TestCase):
def test_trace_lots_of_globals(self):
- count = min(1000, int(support.Py_C_RECURSION_LIMIT * 0.8))
+ count = min(1000, int(support.get_c_recursion_limit() * 0.8))
code = """if 1:
def f():