summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Doc/library/test.rst6
-rw-r--r--Lib/test/support/__init__.py10
-rw-r--r--Lib/test/test_call.py6
-rw-r--r--Modules/_testcapi/parts.h33
-rw-r--r--Modules/_testcapi/vectorcall_limited.c16
-rw-r--r--Modules/_testcapimodule.c12
-rw-r--r--PCbuild/_testcapi.vcxproj4
7 files changed, 64 insertions, 23 deletions
diff --git a/Doc/library/test.rst b/Doc/library/test.rst
index e255952..f3bc7e7 100644
--- a/Doc/library/test.rst
+++ b/Doc/library/test.rst
@@ -794,6 +794,12 @@ The :mod:`test.support` module defines the following functions:
Decorator for only running the test if :data:`HAVE_DOCSTRINGS`.
+.. decorator:: requires_limited_api
+
+ Decorator for only running the test if :ref:`Limited C API <stable>`
+ is available.
+
+
.. decorator:: cpython_only
Decorator for tests only applicable to CPython.
diff --git a/Lib/test/support/__init__.py b/Lib/test/support/__init__.py
index c51a1f2..2409fb0 100644
--- a/Lib/test/support/__init__.py
+++ b/Lib/test/support/__init__.py
@@ -46,6 +46,7 @@ __all__ = [
"anticipate_failure", "load_package_tests", "detect_api_mismatch",
"check__all__", "skip_if_buggy_ucrt_strfptime",
"check_disallow_instantiation", "check_sanitizer", "skip_if_sanitizer",
+ "requires_limited_api",
# sys
"is_jython", "is_android", "is_emscripten", "is_wasi",
"check_impl_detail", "unix_shell", "setswitchinterval",
@@ -1069,6 +1070,15 @@ def refcount_test(test):
return no_tracing(cpython_only(test))
+def requires_limited_api(test):
+ try:
+ import _testcapi
+ except ImportError:
+ return unittest.skip('needs _testcapi module')(test)
+ return unittest.skipUnless(
+ _testcapi.LIMITED_API_AVAILABLE, 'needs Limited API support')(test)
+
+
def _filter_suite(suite, pred):
"""Recursively filter test cases in a suite based on a predicate."""
newtests = []
diff --git a/Lib/test/test_call.py b/Lib/test/test_call.py
index 131b45e..c00de27 100644
--- a/Lib/test/test_call.py
+++ b/Lib/test/test_call.py
@@ -1,5 +1,5 @@
import unittest
-from test.support import cpython_only
+from test.support import cpython_only, requires_limited_api
try:
import _testcapi
except ImportError:
@@ -760,9 +760,7 @@ class TestPEP590(unittest.TestCase):
self.assertEqual(expected, meth(*args1, **kwargs))
self.assertEqual(expected, wrapped(*args, **kwargs))
- @unittest.skipIf(
- hasattr(sys, 'getobjects'),
- "Limited API is not compatible with Py_TRACE_REFS")
+ @requires_limited_api
def test_vectorcall_limited(self):
from _testcapi import pyobject_vectorcall
obj = _testcapi.LimitedVectorCallClass()
diff --git a/Modules/_testcapi/parts.h b/Modules/_testcapi/parts.h
index a76ddd9..304e592 100644
--- a/Modules/_testcapi/parts.h
+++ b/Modules/_testcapi/parts.h
@@ -1,9 +1,36 @@
-#include "Python.h"
+#ifndef Py_TESTCAPI_PARTS_H
+#define Py_TESTCAPI_PARTS_H
+
+#include "pyconfig.h" // for Py_TRACE_REFS
+
+// Figure out if Limited API is available for this build. If it isn't we won't
+// build tests for it.
+// Currently, only Py_TRACE_REFS disables Limited API.
+#ifdef Py_TRACE_REFS
+#undef LIMITED_API_AVAILABLE
+#else
+#define LIMITED_API_AVAILABLE 1
+#endif
-/* Always enable assertions */
+// Always enable assertions
#undef NDEBUG
+#if !defined(LIMITED_API_AVAILABLE) && defined(Py_LIMITED_API)
+// Limited API being unavailable means that with Py_LIMITED_API defined
+// we can't even include Python.h.
+// Do nothing; the .c file that defined Py_LIMITED_API should also do nothing.
+
+#else
+
+#include "Python.h"
+
int _PyTestCapi_Init_Vectorcall(PyObject *module);
-int _PyTestCapi_Init_VectorcallLimited(PyObject *module);
int _PyTestCapi_Init_Heaptype(PyObject *module);
int _PyTestCapi_Init_Unicode(PyObject *module);
+
+#ifdef LIMITED_API_AVAILABLE
+int _PyTestCapi_Init_VectorcallLimited(PyObject *module);
+#endif // LIMITED_API_AVAILABLE
+
+#endif
+#endif // Py_TESTCAPI_PARTS_H
diff --git a/Modules/_testcapi/vectorcall_limited.c b/Modules/_testcapi/vectorcall_limited.c
index c518431..ee57af8 100644
--- a/Modules/_testcapi/vectorcall_limited.c
+++ b/Modules/_testcapi/vectorcall_limited.c
@@ -1,18 +1,8 @@
-#include "pyconfig.h" // Py_TRACE_REFS
-
-#ifdef Py_TRACE_REFS
-
-// Py_TRACE_REFS is incompatible with Limited API
+#define Py_LIMITED_API 0x030c0000 // 3.12
#include "parts.h"
-int
-_PyTestCapi_Init_VectorcallLimited(PyObject *m) {
- return 0;
-}
-#else
+#ifdef LIMITED_API_AVAILABLE
-#define Py_LIMITED_API 0x030c0000 // 3.12
-#include "parts.h"
#include "structmember.h" // PyMemberDef
/* Test Vectorcall in the limited API */
@@ -89,4 +79,4 @@ _PyTestCapi_Init_VectorcallLimited(PyObject *m) {
return 0;
}
-#endif // Py_TRACE_REFS
+#endif // LIMITED_API_AVAILABLE
diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c
index 8d9a0c1..2d4c73c 100644
--- a/Modules/_testcapimodule.c
+++ b/Modules/_testcapimodule.c
@@ -6544,9 +6544,6 @@ PyInit__testcapi(void)
if (_PyTestCapi_Init_Vectorcall(m) < 0) {
return NULL;
}
- if (_PyTestCapi_Init_VectorcallLimited(m) < 0) {
- return NULL;
- }
if (_PyTestCapi_Init_Heaptype(m) < 0) {
return NULL;
}
@@ -6554,6 +6551,15 @@ PyInit__testcapi(void)
return NULL;
}
+#ifndef LIMITED_API_AVAILABLE
+ PyModule_AddObjectRef(m, "LIMITED_API_AVAILABLE", Py_False);
+#else
+ PyModule_AddObjectRef(m, "LIMITED_API_AVAILABLE", Py_True);
+ if (_PyTestCapi_Init_VectorcallLimited(m) < 0) {
+ return NULL;
+ }
+#endif
+
PyState_AddModule(m, &_testcapimodule);
return m;
}
diff --git a/PCbuild/_testcapi.vcxproj b/PCbuild/_testcapi.vcxproj
index 23bb5ec..b7d40c8 100644
--- a/PCbuild/_testcapi.vcxproj
+++ b/PCbuild/_testcapi.vcxproj
@@ -107,6 +107,10 @@
<Project>{cf7ac3d1-e2df-41d2-bea6-1e2556cdea26}</Project>
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
</ProjectReference>
+ <ProjectReference Include="python3dll.vcxproj">
+ <Project>{885d4898-d08d-4091-9c40-c700cfe3fc5a}</Project>
+ <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
+ </ProjectReference>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">