From 23bace26ec265557697cf3b578b361c178070cd5 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Thu, 18 Apr 2019 11:37:26 +0200 Subject: [PATCH] bpo-36635: Add _testinternalcapi module (GH-12841) Add a new _testinternalcapi module to test the internal C API. Move _Py_GetConfigsAsDict() function to the internal C API: _testembed now uses _testinternalcapi to access the function. --- Include/cpython/coreconfig.h | 5 - Include/internal/pycore_coreconfig.h | 5 + Lib/test/pythoninfo.py | 2 +- .../2019-04-15-16-55-49.bpo-36635.__FTq9.rst | 1 + Modules/Setup | 1 + Modules/_testcapimodule.c | 8 -- Modules/_testinternalcapi.c | 45 +++++++++ PCbuild/_testinternalcapi.vcxproj | 94 +++++++++++++++++++ PCbuild/_testinternalcapi.vcxproj.filters | 13 +++ PCbuild/pcbuild.proj | 4 +- PCbuild/pcbuild.sln | 2 + Programs/_testembed.c | 37 +------- setup.py | 4 + 13 files changed, 172 insertions(+), 49 deletions(-) create mode 100644 Misc/NEWS.d/next/Tests/2019-04-15-16-55-49.bpo-36635.__FTq9.rst create mode 100644 Modules/_testinternalcapi.c create mode 100644 PCbuild/_testinternalcapi.vcxproj create mode 100644 PCbuild/_testinternalcapi.vcxproj.filters diff --git a/Include/cpython/coreconfig.h b/Include/cpython/coreconfig.h index 7ce1a02e16c..c1a72989a5e 100644 --- a/Include/cpython/coreconfig.h +++ b/Include/cpython/coreconfig.h @@ -408,11 +408,6 @@ typedef struct { ._init_main = 1} /* Note: _PyCoreConfig_INIT sets other fields to 0/NULL */ - -/* --- Function used for testing ---------------------------------- */ - -PyAPI_FUNC(PyObject*) _Py_GetConfigsAsDict(void); - #ifdef __cplusplus } #endif diff --git a/Include/internal/pycore_coreconfig.h b/Include/internal/pycore_coreconfig.h index 33538442043..e88a46314c8 100644 --- a/Include/internal/pycore_coreconfig.h +++ b/Include/internal/pycore_coreconfig.h @@ -110,6 +110,11 @@ PyAPI_FUNC(_PyInitError) _PyCoreConfig_Read(_PyCoreConfig *config, const _PyArgv *args); PyAPI_FUNC(void) _PyCoreConfig_Write(const _PyCoreConfig *config); + +/* --- Function used for testing ---------------------------------- */ + +PyAPI_FUNC(PyObject*) _Py_GetConfigsAsDict(void); + #ifdef __cplusplus } #endif diff --git a/Lib/test/pythoninfo.py b/Lib/test/pythoninfo.py index 79f7e82e000..19f274a6b62 100644 --- a/Lib/test/pythoninfo.py +++ b/Lib/test/pythoninfo.py @@ -598,7 +598,7 @@ def collect_get_config(info_add): # Dump global configuration variables, _PyCoreConfig # and _PyMainInterpreterConfig try: - from _testcapi import get_configs + from _testinternalcapi import get_configs except ImportError: return diff --git a/Misc/NEWS.d/next/Tests/2019-04-15-16-55-49.bpo-36635.__FTq9.rst b/Misc/NEWS.d/next/Tests/2019-04-15-16-55-49.bpo-36635.__FTq9.rst new file mode 100644 index 00000000000..855d1cb2776 --- /dev/null +++ b/Misc/NEWS.d/next/Tests/2019-04-15-16-55-49.bpo-36635.__FTq9.rst @@ -0,0 +1 @@ +Add a new :mod:`_testinternalcapi` module to test the internal C API. diff --git a/Modules/Setup b/Modules/Setup index 03aa0f16be1..e729ab883f4 100644 --- a/Modules/Setup +++ b/Modules/Setup @@ -173,6 +173,7 @@ _symtable symtablemodule.c #_struct _struct.c # binary structure packing/unpacking #_weakref _weakref.c # basic weak reference support #_testcapi _testcapimodule.c # Python C API test module +#_testinternalcapi _testinternalcapi.c -I$(srcdir)/Include/internal -DPy_BUILD_CORE_MODULE # Python internal C API test module #_random _randommodule.c # Random number generator #_elementtree -I$(srcdir)/Modules/expat -DHAVE_EXPAT_CONFIG_H -DUSE_PYEXPAT_CAPI _elementtree.c # elementtree accelerator #_pickle _pickle.c # pickle accelerator diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c index ae960deba78..6f4eb53d7e9 100644 --- a/Modules/_testcapimodule.c +++ b/Modules/_testcapimodule.c @@ -4736,13 +4736,6 @@ decode_locale_ex(PyObject *self, PyObject *args) } -static PyObject * -get_configs(PyObject *self, PyObject *Py_UNUSED(args)) -{ - return _Py_GetConfigsAsDict(); -} - - #ifdef Py_REF_DEBUG static PyObject * negative_refcount(PyObject *self, PyObject *Py_UNUSED(args)) @@ -4990,7 +4983,6 @@ static PyMethodDef TestMethods[] = { {"bad_get", (PyCFunction)(void(*)(void))bad_get, METH_FASTCALL}, {"EncodeLocaleEx", encode_locale_ex, METH_VARARGS}, {"DecodeLocaleEx", decode_locale_ex, METH_VARARGS}, - {"get_configs", get_configs, METH_NOARGS}, #ifdef Py_REF_DEBUG {"negative_refcount", negative_refcount, METH_NOARGS}, #endif diff --git a/Modules/_testinternalcapi.c b/Modules/_testinternalcapi.c new file mode 100644 index 00000000000..3a43ec16850 --- /dev/null +++ b/Modules/_testinternalcapi.c @@ -0,0 +1,45 @@ +/* + * C Extension module to test Python internal C APIs (Include/internal). + */ + +#if !defined(Py_BUILD_CORE_BUILTIN) && !defined(Py_BUILD_CORE_MODULE) +# error "Py_BUILD_CORE_BUILTIN or Py_BUILD_CORE_MODULE must be defined" +#endif + +#define PY_SSIZE_T_CLEAN + +#include "Python.h" +#include "pycore_coreconfig.h" + + +static PyObject * +get_configs(PyObject *self, PyObject *Py_UNUSED(args)) +{ + return _Py_GetConfigsAsDict(); +} + + +static PyMethodDef TestMethods[] = { + {"get_configs", get_configs, METH_NOARGS}, + {NULL, NULL} /* sentinel */ +}; + + +static struct PyModuleDef _testcapimodule = { + PyModuleDef_HEAD_INIT, + "_testinternalcapi", + NULL, + -1, + TestMethods, + NULL, + NULL, + NULL, + NULL +}; + + +PyMODINIT_FUNC +PyInit__testinternalcapi(void) +{ + return PyModule_Create(&_testcapimodule); +} diff --git a/PCbuild/_testinternalcapi.vcxproj b/PCbuild/_testinternalcapi.vcxproj new file mode 100644 index 00000000000..116d193a39c --- /dev/null +++ b/PCbuild/_testinternalcapi.vcxproj @@ -0,0 +1,94 @@ + + + + + Debug + ARM + + + Debug + Win32 + + + Debug + x64 + + + PGInstrument + ARM + + + PGInstrument + Win32 + + + PGInstrument + x64 + + + PGUpdate + ARM + + + PGUpdate + Win32 + + + PGUpdate + x64 + + + Release + ARM + + + Release + Win32 + + + Release + x64 + + + + {900342D7-516A-4469-B1AD-59A66E49A25F} + _testinternalcapi + Win32Proj + false + + + + + DynamicLibrary + NotSet + + + + .pyd + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + + + + + + + + + + {cf7ac3d1-e2df-41d2-bea6-1e2556cdea26} + false + + + + + + diff --git a/PCbuild/_testinternalcapi.vcxproj.filters b/PCbuild/_testinternalcapi.vcxproj.filters new file mode 100644 index 00000000000..4644f230be1 --- /dev/null +++ b/PCbuild/_testinternalcapi.vcxproj.filters @@ -0,0 +1,13 @@ + + + + + {136fc5eb-7fe4-4486-8c6d-b49f37a00199} + + + + + Source Files + + + diff --git a/PCbuild/pcbuild.proj b/PCbuild/pcbuild.proj index 574c4f02913..d16ddef89f6 100644 --- a/PCbuild/pcbuild.proj +++ b/PCbuild/pcbuild.proj @@ -62,13 +62,13 @@ - + false - + diff --git a/PCbuild/pcbuild.sln b/PCbuild/pcbuild.sln index e9239365b5c..951dc932a8e 100644 --- a/PCbuild/pcbuild.sln +++ b/PCbuild/pcbuild.sln @@ -37,6 +37,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_ssl", "_ssl.vcxproj", "{C6 EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_testcapi", "_testcapi.vcxproj", "{6901D91C-6E48-4BB7-9FEC-700C8131DF1D}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_testinternalcapi", "_testinternalcapi.vcxproj", "{900342D7-516A-4469-B1AD-59A66E49A25F}" +EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_testimportmultiple", "_testimportmultiple.vcxproj", "{36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_tkinter", "_tkinter.vcxproj", "{4946ECAC-2E69-4BF8-A90A-F5136F5094DF}" diff --git a/Programs/_testembed.c b/Programs/_testembed.c index 7d71a961602..3fc8e6d8c6b 100644 --- a/Programs/_testembed.c +++ b/Programs/_testembed.c @@ -298,42 +298,13 @@ static int test_initialize_pymain(void) } -static int -dump_config_impl(void) -{ - PyObject *config = _Py_GetConfigsAsDict(); - if (config == NULL) { - return -1; - } - - PyObject *res; - PyObject *json = PyImport_ImportModule("json"); - if (json) { - res = PyObject_CallMethod(json, "dumps", "O", config); - Py_DECREF(json); - } - else { - res = NULL; - } - Py_CLEAR(config); - if (res == NULL) { - return -1; - } - - PySys_FormatStdout("%S\n", res); - Py_DECREF(res); - - return 0; -} - - static void dump_config(void) { - if (dump_config_impl() < 0) { - fprintf(stderr, "failed to dump the configuration:\n"); - PyErr_Print(); - } + (void) PyRun_SimpleStringFlags( + "import _testinternalcapi, json; " + "print(json.dumps(_testinternalcapi.get_configs()))", + 0); } diff --git a/setup.py b/setup.py index c470719a6a8..3d6404f89ee 100644 --- a/setup.py +++ b/setup.py @@ -814,6 +814,10 @@ class PyBuildExt(build_ext): self.add(Extension('_testcapi', ['_testcapimodule.c'], depends=['testcapi_long.h'])) + # Python Internal C API test module + self.add(Extension('_testinternalcapi', ['_testinternalcapi.c'], + extra_compile_args=['-D Py_BUILD_CORE_MODULE'])) + # Python PEP-3118 (buffer protocol) test module self.add(Extension('_testbuffer', ['_testbuffer.c']))