Skip to content

gh-109723: Disable Py_BUILD_CORE in _testcapi #109727

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Sep 22, 2023
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
19 changes: 1 addition & 18 deletions Modules/_testcapi/clinic/long.c.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

53 changes: 0 additions & 53 deletions Modules/_testcapi/long.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

#include "parts.h"
#include "clinic/long.c.h"
#include "pycore_long.h" // _PyLong_Sign()

/*[clinic input]
module _testcapi
Expand Down Expand Up @@ -535,57 +534,6 @@ _testcapi_test_long_as_double_impl(PyObject *module)
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]
_testcapi.call_long_compact_api
arg: object
Expand Down Expand Up @@ -631,7 +579,6 @@ static PyMethodDef test_methods[] = {
_TESTCAPI_TEST_LONG_AS_SIZE_T_METHODDEF
_TESTCAPI_TEST_LONG_AS_UNSIGNED_LONG_LONG_MASK_METHODDEF
_TESTCAPI_TEST_LONG_LONG_AND_OVERFLOW_METHODDEF
_TESTCAPI_TEST_LONG_NUMBITS_METHODDEF
_TESTCAPI_TEST_LONGLONG_API_METHODDEF
_TESTCAPI_CALL_LONG_COMPACT_API_METHODDEF
_TESTCAPI_PYLONG_ASINT_METHODDEF
Expand Down
16 changes: 16 additions & 0 deletions Modules/_testcapi/parts.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,24 @@
// Always enable assertions
#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"

#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_Heaptype(PyObject *module);
int _PyTestCapi_Init_Abstract(PyObject *module);
Expand Down
4 changes: 0 additions & 4 deletions Modules/_testcapi/pyatomic.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,6 @@
* This only tests basic functionality, not any synchronizing ordering.
*/

/* Always enable assertions */
#undef NDEBUG

#include "Python.h"
#include "parts.h"

// We define atomic bitwise operations on these types
Expand Down
25 changes: 6 additions & 19 deletions Modules/_testcapimodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,13 @@
* standard Python regression test, via Lib/test/test_capi.py.
*/

/* This module tests the public (Include/ and Include/cpython/) C API.
The internal C API must not be used here: use _testinternalcapi for that.

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 parts.h first since it takes care of NDEBUG and Py_BUILD_CORE macros
// and including Python.h.
//
// Several parts of this module are broken out into files in _testcapi/.
// Include definitions from there.
#include "_testcapi/parts.h"

#include "Python.h"
#include "frameobject.h" // PyFrame_New()
#include "marshal.h" // PyMarshal_WriteLongToFile()

Expand All @@ -29,17 +23,10 @@
# include <sys/wait.h> // W_STOPCODE
#endif

#ifdef Py_BUILD_CORE
# error "_testcapi must test the public Python C API, not CPython internal C API"
#endif

#ifdef bool
# error "The public headers should not include <stdbool.h>, see gh-48924"
#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"


Expand Down
62 changes: 62 additions & 0 deletions Modules/_testinternalcapi.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include "pycore_hashtable.h" // _Py_hashtable_new()
#include "pycore_initconfig.h" // _Py_GetConfigsAsDict()
#include "pycore_interp.h" // _PyInterpreterState_GetConfigCopy()
#include "pycore_long.h" // _PyLong_Sign()
#include "pycore_object.h" // _PyObject_IsFreed()
#include "pycore_pathconfig.h" // _PyPathConfig_ClearGlobal()
#include "pycore_pyerrors.h" // _PyErr_ChainExceptions1()
Expand Down Expand Up @@ -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[] = {
{"get_configs", get_configs, METH_NOARGS},
{"get_recursion_depth", get_recursion_depth, METH_NOARGS},
Expand Down Expand Up @@ -1521,6 +1582,7 @@ static PyMethodDef module_functions[] = {
_PyCFunction_CAST(run_in_subinterp_with_config),
METH_VARARGS | METH_KEYWORDS},
_TESTINTERNALCAPI_WRITE_UNRAISABLE_EXC_METHODDEF
_TESTINTERNALCAPI_TEST_LONG_NUMBITS_METHODDEF
{NULL, NULL} /* sentinel */
};

Expand Down
19 changes: 18 additions & 1 deletion Modules/clinic/_testinternalcapi.c.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

17 changes: 11 additions & 6 deletions Tools/c-analyzer/c_parser/preprocessor/gcc.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,20 @@

from . import common as _common

# The following C files define the Py_LIMITED_API macro, and so must not be
# built with the Py_BUILD_CORE macro defined.
USE_LIMITED_C_API = frozenset((
# The following C files must not built with Py_BUILD_CORE.
FILES_WITHOUT_INTERNAL_CAPI = frozenset((
# Modules/
'_testcapimodule.c',
'_testclinic_limited.c',
'xxlimited.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/
'heaptype_relative.c',
'vectorcall_limited.c',
'_testcapi',
))

TOOL = 'gcc'
Expand Down Expand Up @@ -75,7 +77,10 @@ def preprocess(filename,
filename = _normpath(filename, cwd)

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',)

text = _common.preprocess(
Expand Down