mirror of https://github.com/python/cpython
gh-109723: Disable Py_BUILD_CORE in _testcapi (#109727)
Make sure that the internal C API is not tested by mistake by _testcapi. Undefine Py_BUILD_CORE_BUILTIN and Py_BUILD_CORE_MODULE macros in Modules/_testcapi/parts.h: move code from _testcapimodule.c. heaptype_relative.c and vectorcall_limited.c are using the limited C API which is incompatible with the internal C API. Move test_long_numbits() from _testcapi to _testinternalcapi since it uses the internal C API "pycore_long.h". Fix Modules/_testcapi/pyatomic.c: don't include Python.h directly, just include _testcapi/parts.h. Ajust "make check-c-globals" for these changes.
This commit is contained in:
parent
c32abf1f21
commit
09a25616a9
|
@ -133,23 +133,6 @@ _testcapi_test_long_as_double(PyObject *module, PyObject *Py_UNUSED(ignored))
|
||||||
return _testcapi_test_long_as_double_impl(module);
|
return _testcapi_test_long_as_double_impl(module);
|
||||||
}
|
}
|
||||||
|
|
||||||
PyDoc_STRVAR(_testcapi_test_long_numbits__doc__,
|
|
||||||
"test_long_numbits($module, /)\n"
|
|
||||||
"--\n"
|
|
||||||
"\n");
|
|
||||||
|
|
||||||
#define _TESTCAPI_TEST_LONG_NUMBITS_METHODDEF \
|
|
||||||
{"test_long_numbits", (PyCFunction)_testcapi_test_long_numbits, METH_NOARGS, _testcapi_test_long_numbits__doc__},
|
|
||||||
|
|
||||||
static PyObject *
|
|
||||||
_testcapi_test_long_numbits_impl(PyObject *module);
|
|
||||||
|
|
||||||
static PyObject *
|
|
||||||
_testcapi_test_long_numbits(PyObject *module, PyObject *Py_UNUSED(ignored))
|
|
||||||
{
|
|
||||||
return _testcapi_test_long_numbits_impl(module);
|
|
||||||
}
|
|
||||||
|
|
||||||
PyDoc_STRVAR(_testcapi_call_long_compact_api__doc__,
|
PyDoc_STRVAR(_testcapi_call_long_compact_api__doc__,
|
||||||
"call_long_compact_api($module, arg, /)\n"
|
"call_long_compact_api($module, arg, /)\n"
|
||||||
"--\n"
|
"--\n"
|
||||||
|
@ -165,4 +148,4 @@ PyDoc_STRVAR(_testcapi_PyLong_AsInt__doc__,
|
||||||
|
|
||||||
#define _TESTCAPI_PYLONG_ASINT_METHODDEF \
|
#define _TESTCAPI_PYLONG_ASINT_METHODDEF \
|
||||||
{"PyLong_AsInt", (PyCFunction)_testcapi_PyLong_AsInt, METH_O, _testcapi_PyLong_AsInt__doc__},
|
{"PyLong_AsInt", (PyCFunction)_testcapi_PyLong_AsInt, METH_O, _testcapi_PyLong_AsInt__doc__},
|
||||||
/*[clinic end generated code: output=31267ab2dd90aa1d input=a9049054013a1b77]*/
|
/*[clinic end generated code: output=de762870526e241d input=a9049054013a1b77]*/
|
||||||
|
|
|
@ -4,7 +4,6 @@
|
||||||
|
|
||||||
#include "parts.h"
|
#include "parts.h"
|
||||||
#include "clinic/long.c.h"
|
#include "clinic/long.c.h"
|
||||||
#include "pycore_long.h" // _PyLong_Sign()
|
|
||||||
|
|
||||||
/*[clinic input]
|
/*[clinic input]
|
||||||
module _testcapi
|
module _testcapi
|
||||||
|
@ -535,57 +534,6 @@ _testcapi_test_long_as_double_impl(PyObject *module)
|
||||||
return Py_None;
|
return Py_None;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*[clinic input]
|
|
||||||
_testcapi.test_long_numbits
|
|
||||||
[clinic start generated code]*/
|
|
||||||
|
|
||||||
static PyObject *
|
|
||||||
_testcapi_test_long_numbits_impl(PyObject *module)
|
|
||||||
/*[clinic end generated code: output=9eaf8458cb15d7f7 input=265c02d48a13059e]*/
|
|
||||||
{
|
|
||||||
struct triple {
|
|
||||||
long input;
|
|
||||||
size_t nbits;
|
|
||||||
int sign;
|
|
||||||
} testcases[] = {{0, 0, 0},
|
|
||||||
{1L, 1, 1},
|
|
||||||
{-1L, 1, -1},
|
|
||||||
{2L, 2, 1},
|
|
||||||
{-2L, 2, -1},
|
|
||||||
{3L, 2, 1},
|
|
||||||
{-3L, 2, -1},
|
|
||||||
{4L, 3, 1},
|
|
||||||
{-4L, 3, -1},
|
|
||||||
{0x7fffL, 15, 1}, /* one Python int digit */
|
|
||||||
{-0x7fffL, 15, -1},
|
|
||||||
{0xffffL, 16, 1},
|
|
||||||
{-0xffffL, 16, -1},
|
|
||||||
{0xfffffffL, 28, 1},
|
|
||||||
{-0xfffffffL, 28, -1}};
|
|
||||||
size_t i;
|
|
||||||
|
|
||||||
for (i = 0; i < Py_ARRAY_LENGTH(testcases); ++i) {
|
|
||||||
size_t nbits;
|
|
||||||
int sign;
|
|
||||||
PyObject *plong;
|
|
||||||
|
|
||||||
plong = PyLong_FromLong(testcases[i].input);
|
|
||||||
if (plong == NULL)
|
|
||||||
return NULL;
|
|
||||||
nbits = _PyLong_NumBits(plong);
|
|
||||||
sign = _PyLong_Sign(plong);
|
|
||||||
|
|
||||||
Py_DECREF(plong);
|
|
||||||
if (nbits != testcases[i].nbits)
|
|
||||||
return raiseTestError("test_long_numbits",
|
|
||||||
"wrong result for _PyLong_NumBits");
|
|
||||||
if (sign != testcases[i].sign)
|
|
||||||
return raiseTestError("test_long_numbits",
|
|
||||||
"wrong result for _PyLong_Sign");
|
|
||||||
}
|
|
||||||
Py_RETURN_NONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*[clinic input]
|
/*[clinic input]
|
||||||
_testcapi.call_long_compact_api
|
_testcapi.call_long_compact_api
|
||||||
arg: object
|
arg: object
|
||||||
|
@ -631,7 +579,6 @@ static PyMethodDef test_methods[] = {
|
||||||
_TESTCAPI_TEST_LONG_AS_SIZE_T_METHODDEF
|
_TESTCAPI_TEST_LONG_AS_SIZE_T_METHODDEF
|
||||||
_TESTCAPI_TEST_LONG_AS_UNSIGNED_LONG_LONG_MASK_METHODDEF
|
_TESTCAPI_TEST_LONG_AS_UNSIGNED_LONG_LONG_MASK_METHODDEF
|
||||||
_TESTCAPI_TEST_LONG_LONG_AND_OVERFLOW_METHODDEF
|
_TESTCAPI_TEST_LONG_LONG_AND_OVERFLOW_METHODDEF
|
||||||
_TESTCAPI_TEST_LONG_NUMBITS_METHODDEF
|
|
||||||
_TESTCAPI_TEST_LONGLONG_API_METHODDEF
|
_TESTCAPI_TEST_LONGLONG_API_METHODDEF
|
||||||
_TESTCAPI_CALL_LONG_COMPACT_API_METHODDEF
|
_TESTCAPI_CALL_LONG_COMPACT_API_METHODDEF
|
||||||
_TESTCAPI_PYLONG_ASINT_METHODDEF
|
_TESTCAPI_PYLONG_ASINT_METHODDEF
|
||||||
|
|
|
@ -4,8 +4,24 @@
|
||||||
// Always enable assertions
|
// Always enable assertions
|
||||||
#undef NDEBUG
|
#undef NDEBUG
|
||||||
|
|
||||||
|
// The _testcapi extension tests the public C API: header files in Include/ and
|
||||||
|
// Include/cpython/ directories. The internal C API must not be tested by
|
||||||
|
// _testcapi: use _testinternalcapi for that.
|
||||||
|
//
|
||||||
|
// _testcapi C files can built with the Py_BUILD_CORE_BUILTIN macro defined if
|
||||||
|
// one of the Modules/Setup files asks to build _testcapi as "static"
|
||||||
|
// (gh-109723).
|
||||||
|
//
|
||||||
|
// The Visual Studio projects builds _testcapi with Py_BUILD_CORE_MODULE.
|
||||||
|
#undef Py_BUILD_CORE_MODULE
|
||||||
|
#undef Py_BUILD_CORE_BUILTIN
|
||||||
|
|
||||||
#include "Python.h"
|
#include "Python.h"
|
||||||
|
|
||||||
|
#ifdef Py_BUILD_CORE
|
||||||
|
# error "_testcapi must test the public Python C API, not the internal C API"
|
||||||
|
#endif
|
||||||
|
|
||||||
int _PyTestCapi_Init_Vectorcall(PyObject *module);
|
int _PyTestCapi_Init_Vectorcall(PyObject *module);
|
||||||
int _PyTestCapi_Init_Heaptype(PyObject *module);
|
int _PyTestCapi_Init_Heaptype(PyObject *module);
|
||||||
int _PyTestCapi_Init_Abstract(PyObject *module);
|
int _PyTestCapi_Init_Abstract(PyObject *module);
|
||||||
|
|
|
@ -4,10 +4,6 @@
|
||||||
* This only tests basic functionality, not any synchronizing ordering.
|
* This only tests basic functionality, not any synchronizing ordering.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Always enable assertions */
|
|
||||||
#undef NDEBUG
|
|
||||||
|
|
||||||
#include "Python.h"
|
|
||||||
#include "parts.h"
|
#include "parts.h"
|
||||||
|
|
||||||
// We define atomic bitwise operations on these types
|
// We define atomic bitwise operations on these types
|
||||||
|
|
|
@ -5,19 +5,13 @@
|
||||||
* standard Python regression test, via Lib/test/test_capi.py.
|
* standard Python regression test, via Lib/test/test_capi.py.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* This module tests the public (Include/ and Include/cpython/) C API.
|
// Include parts.h first since it takes care of NDEBUG and Py_BUILD_CORE macros
|
||||||
The internal C API must not be used here: use _testinternalcapi for that.
|
// and including Python.h.
|
||||||
|
//
|
||||||
|
// Several parts of this module are broken out into files in _testcapi/.
|
||||||
|
// Include definitions from there.
|
||||||
|
#include "_testcapi/parts.h"
|
||||||
|
|
||||||
The Visual Studio projects builds _testcapi with Py_BUILD_CORE_MODULE
|
|
||||||
macro defined, but only the public C API must be tested here. */
|
|
||||||
|
|
||||||
#undef Py_BUILD_CORE_MODULE
|
|
||||||
#undef Py_BUILD_CORE_BUILTIN
|
|
||||||
|
|
||||||
/* Always enable assertions */
|
|
||||||
#undef NDEBUG
|
|
||||||
|
|
||||||
#include "Python.h"
|
|
||||||
#include "frameobject.h" // PyFrame_New()
|
#include "frameobject.h" // PyFrame_New()
|
||||||
#include "marshal.h" // PyMarshal_WriteLongToFile()
|
#include "marshal.h" // PyMarshal_WriteLongToFile()
|
||||||
|
|
||||||
|
@ -29,17 +23,10 @@
|
||||||
# include <sys/wait.h> // W_STOPCODE
|
# include <sys/wait.h> // W_STOPCODE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef Py_BUILD_CORE
|
|
||||||
# error "_testcapi must test the public Python C API, not CPython internal C API"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef bool
|
#ifdef bool
|
||||||
# error "The public headers should not include <stdbool.h>, see gh-48924"
|
# error "The public headers should not include <stdbool.h>, see gh-48924"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Several parts of this module are broken out into files in _testcapi/.
|
|
||||||
// Include definitions from there.
|
|
||||||
#include "_testcapi/parts.h"
|
|
||||||
#include "_testcapi/util.h"
|
#include "_testcapi/util.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
#include "pycore_hashtable.h" // _Py_hashtable_new()
|
#include "pycore_hashtable.h" // _Py_hashtable_new()
|
||||||
#include "pycore_initconfig.h" // _Py_GetConfigsAsDict()
|
#include "pycore_initconfig.h" // _Py_GetConfigsAsDict()
|
||||||
#include "pycore_interp.h" // _PyInterpreterState_GetConfigCopy()
|
#include "pycore_interp.h" // _PyInterpreterState_GetConfigCopy()
|
||||||
|
#include "pycore_long.h" // _PyLong_Sign()
|
||||||
#include "pycore_object.h" // _PyObject_IsFreed()
|
#include "pycore_object.h" // _PyObject_IsFreed()
|
||||||
#include "pycore_pathconfig.h" // _PyPathConfig_ClearGlobal()
|
#include "pycore_pathconfig.h" // _PyPathConfig_ClearGlobal()
|
||||||
#include "pycore_pyerrors.h" // _PyErr_ChainExceptions1()
|
#include "pycore_pyerrors.h" // _PyErr_ChainExceptions1()
|
||||||
|
@ -1466,6 +1467,66 @@ _testinternalcapi_write_unraisable_exc_impl(PyObject *module, PyObject *exc,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
raiseTestError(const char* test_name, const char* msg)
|
||||||
|
{
|
||||||
|
PyErr_Format(PyExc_AssertionError, "%s: %s", test_name, msg);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*[clinic input]
|
||||||
|
_testinternalcapi.test_long_numbits
|
||||||
|
[clinic start generated code]*/
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
_testinternalcapi_test_long_numbits_impl(PyObject *module)
|
||||||
|
/*[clinic end generated code: output=745d62d120359434 input=f14ca6f638e44dad]*/
|
||||||
|
{
|
||||||
|
struct triple {
|
||||||
|
long input;
|
||||||
|
size_t nbits;
|
||||||
|
int sign;
|
||||||
|
} testcases[] = {{0, 0, 0},
|
||||||
|
{1L, 1, 1},
|
||||||
|
{-1L, 1, -1},
|
||||||
|
{2L, 2, 1},
|
||||||
|
{-2L, 2, -1},
|
||||||
|
{3L, 2, 1},
|
||||||
|
{-3L, 2, -1},
|
||||||
|
{4L, 3, 1},
|
||||||
|
{-4L, 3, -1},
|
||||||
|
{0x7fffL, 15, 1}, /* one Python int digit */
|
||||||
|
{-0x7fffL, 15, -1},
|
||||||
|
{0xffffL, 16, 1},
|
||||||
|
{-0xffffL, 16, -1},
|
||||||
|
{0xfffffffL, 28, 1},
|
||||||
|
{-0xfffffffL, 28, -1}};
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
for (i = 0; i < Py_ARRAY_LENGTH(testcases); ++i) {
|
||||||
|
size_t nbits;
|
||||||
|
int sign;
|
||||||
|
PyObject *plong;
|
||||||
|
|
||||||
|
plong = PyLong_FromLong(testcases[i].input);
|
||||||
|
if (plong == NULL)
|
||||||
|
return NULL;
|
||||||
|
nbits = _PyLong_NumBits(plong);
|
||||||
|
sign = _PyLong_Sign(plong);
|
||||||
|
|
||||||
|
Py_DECREF(plong);
|
||||||
|
if (nbits != testcases[i].nbits)
|
||||||
|
return raiseTestError("test_long_numbits",
|
||||||
|
"wrong result for _PyLong_NumBits");
|
||||||
|
if (sign != testcases[i].sign)
|
||||||
|
return raiseTestError("test_long_numbits",
|
||||||
|
"wrong result for _PyLong_Sign");
|
||||||
|
}
|
||||||
|
Py_RETURN_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static PyMethodDef module_functions[] = {
|
static PyMethodDef module_functions[] = {
|
||||||
{"get_configs", get_configs, METH_NOARGS},
|
{"get_configs", get_configs, METH_NOARGS},
|
||||||
{"get_recursion_depth", get_recursion_depth, METH_NOARGS},
|
{"get_recursion_depth", get_recursion_depth, METH_NOARGS},
|
||||||
|
@ -1521,6 +1582,7 @@ static PyMethodDef module_functions[] = {
|
||||||
_PyCFunction_CAST(run_in_subinterp_with_config),
|
_PyCFunction_CAST(run_in_subinterp_with_config),
|
||||||
METH_VARARGS | METH_KEYWORDS},
|
METH_VARARGS | METH_KEYWORDS},
|
||||||
_TESTINTERNALCAPI_WRITE_UNRAISABLE_EXC_METHODDEF
|
_TESTINTERNALCAPI_WRITE_UNRAISABLE_EXC_METHODDEF
|
||||||
|
_TESTINTERNALCAPI_TEST_LONG_NUMBITS_METHODDEF
|
||||||
{NULL, NULL} /* sentinel */
|
{NULL, NULL} /* sentinel */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -296,4 +296,21 @@ _testinternalcapi_write_unraisable_exc(PyObject *module, PyObject *const *args,
|
||||||
exit:
|
exit:
|
||||||
return return_value;
|
return return_value;
|
||||||
}
|
}
|
||||||
/*[clinic end generated code: output=c7156622e80df1ce input=a9049054013a1b77]*/
|
|
||||||
|
PyDoc_STRVAR(_testinternalcapi_test_long_numbits__doc__,
|
||||||
|
"test_long_numbits($module, /)\n"
|
||||||
|
"--\n"
|
||||||
|
"\n");
|
||||||
|
|
||||||
|
#define _TESTINTERNALCAPI_TEST_LONG_NUMBITS_METHODDEF \
|
||||||
|
{"test_long_numbits", (PyCFunction)_testinternalcapi_test_long_numbits, METH_NOARGS, _testinternalcapi_test_long_numbits__doc__},
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
_testinternalcapi_test_long_numbits_impl(PyObject *module);
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
_testinternalcapi_test_long_numbits(PyObject *module, PyObject *Py_UNUSED(ignored))
|
||||||
|
{
|
||||||
|
return _testinternalcapi_test_long_numbits_impl(module);
|
||||||
|
}
|
||||||
|
/*[clinic end generated code: output=59144f59957627bd input=a9049054013a1b77]*/
|
||||||
|
|
|
@ -3,18 +3,20 @@ import re
|
||||||
|
|
||||||
from . import common as _common
|
from . import common as _common
|
||||||
|
|
||||||
# The following C files define the Py_LIMITED_API macro, and so must not be
|
# The following C files must not built with Py_BUILD_CORE.
|
||||||
# built with the Py_BUILD_CORE macro defined.
|
FILES_WITHOUT_INTERNAL_CAPI = frozenset((
|
||||||
USE_LIMITED_C_API = frozenset((
|
|
||||||
# Modules/
|
# Modules/
|
||||||
'_testcapimodule.c',
|
'_testcapimodule.c',
|
||||||
'_testclinic_limited.c',
|
'_testclinic_limited.c',
|
||||||
'xxlimited.c',
|
'xxlimited.c',
|
||||||
'xxlimited_35.c',
|
'xxlimited_35.c',
|
||||||
|
))
|
||||||
|
|
||||||
|
# C files in the fhe following directories must not be built with
|
||||||
|
# Py_BUILD_CORE.
|
||||||
|
DIRS_WITHOUT_INTERNAL_CAPI = frozenset((
|
||||||
# Modules/_testcapi/
|
# Modules/_testcapi/
|
||||||
'heaptype_relative.c',
|
'_testcapi',
|
||||||
'vectorcall_limited.c',
|
|
||||||
))
|
))
|
||||||
|
|
||||||
TOOL = 'gcc'
|
TOOL = 'gcc'
|
||||||
|
@ -75,7 +77,10 @@ def preprocess(filename,
|
||||||
filename = _normpath(filename, cwd)
|
filename = _normpath(filename, cwd)
|
||||||
|
|
||||||
postargs = POST_ARGS
|
postargs = POST_ARGS
|
||||||
if os.path.basename(filename) not in USE_LIMITED_C_API:
|
basename = os.path.basename(filename)
|
||||||
|
dirname = os.path.basename(os.path.dirname(filename))
|
||||||
|
if (basename not in FILES_WITHOUT_INTERNAL_CAPI
|
||||||
|
and dirname not in DIRS_WITHOUT_INTERNAL_CAPI):
|
||||||
postargs += ('-DPy_BUILD_CORE=1',)
|
postargs += ('-DPy_BUILD_CORE=1',)
|
||||||
|
|
||||||
text = _common.preprocess(
|
text = _common.preprocess(
|
||||||
|
|
Loading…
Reference in New Issue