From 5ed6995675b084fe583b71f96fdde4413bb2a77b Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 6 Nov 2018 15:59:52 +0100 Subject: [PATCH] bpo-35081: Add _PyCoreConfig_AsDict() (GH-10362) _testcapimodule.c must not include pycore_pathconfig.h, since it's an internal header files. Changes: * Add _PyCoreConfig_AsDict() function to coreconfig.c. * Remove pycore_pathconfig.h include from _testcapimodule.h. * pycore_pathconfig.h now requires Py_BUILD_CORE to be defined. * _testcapimodule.c compilation now fails if it's built with Py_BUILD_CORE defined. --- Include/coreconfig.h | 5 +- Include/internal/pycore_pathconfig.h | 4 + Modules/_testcapimodule.c | 152 +-------------------------- Python/coreconfig.c | 152 +++++++++++++++++++++++++++ 4 files changed, 164 insertions(+), 149 deletions(-) diff --git a/Include/coreconfig.h b/Include/coreconfig.h index ff7b684a1f..a7d3983d4d 100644 --- a/Include/coreconfig.h +++ b/Include/coreconfig.h @@ -358,9 +358,10 @@ PyAPI_FUNC(int) _PyCoreConfig_GetEnvDup( wchar_t **dest, wchar_t *wname, char *name); -#endif - +/* Used by _testcapi.get_coreconfig() */ +PyAPI_FUNC(PyObject *) _PyCoreConfig_AsDict(const _PyCoreConfig *config); +#endif #ifdef __cplusplus } diff --git a/Include/internal/pycore_pathconfig.h b/Include/internal/pycore_pathconfig.h index 395df498a0..00d7bbf23e 100644 --- a/Include/internal/pycore_pathconfig.h +++ b/Include/internal/pycore_pathconfig.h @@ -4,6 +4,10 @@ extern "C" { #endif +#ifndef Py_BUILD_CORE +# error "Py_BUILD_CORE must be defined to include this header" +#endif + PyAPI_FUNC(void) _Py_wstrlist_clear( int len, wchar_t **list); diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c index e2deb2603d..3133d2b11f 100644 --- a/Modules/_testcapimodule.c +++ b/Modules/_testcapimodule.c @@ -10,7 +10,6 @@ #include "Python.h" #include "datetime.h" #include "marshal.h" -#include "pycore_pathconfig.h" #include "pythread.h" #include "structmember.h" #include @@ -24,6 +23,10 @@ #include /* For W_STOPCODE */ #endif +#ifdef Py_BUILD_CORE +# error "_testcapi must test the public Python C API, not CPython internal C API" +#endif + static PyObject *TestError; /* set to exception object in init */ /* Raise TestError with test_name + ": " + msg, and return NULL. */ @@ -4670,152 +4673,7 @@ get_coreconfig(PyObject *self, PyObject *Py_UNUSED(args)) { PyInterpreterState *interp = _PyInterpreterState_Get(); const _PyCoreConfig *config = &interp->core_config; - PyObject *dict, *obj; - - dict = PyDict_New(); - if (dict == NULL) { - return NULL; - } - -#define FROM_STRING(STR) \ - ((STR != NULL) ? \ - PyUnicode_FromString(STR) \ - : (Py_INCREF(Py_None), Py_None)) -#define FROM_WSTRING(STR) \ - ((STR != NULL) ? \ - PyUnicode_FromWideChar(STR, -1) \ - : (Py_INCREF(Py_None), Py_None)) -#define SET_ITEM(KEY, EXPR) \ - do { \ - obj = (EXPR); \ - if (obj == NULL) { \ - return NULL; \ - } \ - int res = PyDict_SetItemString(dict, (KEY), obj); \ - Py_DECREF(obj); \ - if (res < 0) { \ - goto fail; \ - } \ - } while (0) - - SET_ITEM("install_signal_handlers", - PyLong_FromLong(config->install_signal_handlers)); - SET_ITEM("use_environment", - PyLong_FromLong(config->use_environment)); - SET_ITEM("use_hash_seed", - PyLong_FromLong(config->use_hash_seed)); - SET_ITEM("hash_seed", - PyLong_FromUnsignedLong(config->hash_seed)); - SET_ITEM("allocator", - FROM_STRING(config->allocator)); - SET_ITEM("dev_mode", - PyLong_FromLong(config->dev_mode)); - SET_ITEM("faulthandler", - PyLong_FromLong(config->faulthandler)); - SET_ITEM("tracemalloc", - PyLong_FromLong(config->tracemalloc)); - SET_ITEM("import_time", - PyLong_FromLong(config->import_time)); - SET_ITEM("show_ref_count", - PyLong_FromLong(config->show_ref_count)); - SET_ITEM("show_alloc_count", - PyLong_FromLong(config->show_alloc_count)); - SET_ITEM("dump_refs", - PyLong_FromLong(config->dump_refs)); - SET_ITEM("malloc_stats", - PyLong_FromLong(config->malloc_stats)); - SET_ITEM("coerce_c_locale", - PyLong_FromLong(config->coerce_c_locale)); - SET_ITEM("coerce_c_locale_warn", - PyLong_FromLong(config->coerce_c_locale_warn)); - SET_ITEM("filesystem_encoding", - FROM_STRING(config->filesystem_encoding)); - SET_ITEM("filesystem_errors", - FROM_STRING(config->filesystem_errors)); - SET_ITEM("stdio_encoding", - FROM_STRING(config->stdio_encoding)); - SET_ITEM("utf8_mode", - PyLong_FromLong(config->utf8_mode)); - SET_ITEM("pycache_prefix", - FROM_WSTRING(config->pycache_prefix)); - SET_ITEM("program_name", - FROM_WSTRING(config->program_name)); - SET_ITEM("argv", - _Py_wstrlist_as_pylist(config->argc, config->argv)); - SET_ITEM("program", - FROM_WSTRING(config->program)); - SET_ITEM("warnoptions", - _Py_wstrlist_as_pylist(config->nwarnoption, config->warnoptions)); - SET_ITEM("module_search_path_env", - FROM_WSTRING(config->module_search_path_env)); - SET_ITEM("home", - FROM_WSTRING(config->home)); - SET_ITEM("module_search_paths", - _Py_wstrlist_as_pylist(config->nmodule_search_path, config->module_search_paths)); - SET_ITEM("executable", - FROM_WSTRING(config->executable)); - SET_ITEM("prefix", - FROM_WSTRING(config->prefix)); - SET_ITEM("base_prefix", - FROM_WSTRING(config->base_prefix)); - SET_ITEM("exec_prefix", - FROM_WSTRING(config->exec_prefix)); - SET_ITEM("base_exec_prefix", - FROM_WSTRING(config->base_exec_prefix)); -#ifdef MS_WINDOWS - SET_ITEM("dll_path", - FROM_WSTRING(config->dll_path)); -#endif - SET_ITEM("isolated", - PyLong_FromLong(config->isolated)); - SET_ITEM("site_import", - PyLong_FromLong(config->site_import)); - SET_ITEM("bytes_warning", - PyLong_FromLong(config->bytes_warning)); - SET_ITEM("inspect", - PyLong_FromLong(config->inspect)); - SET_ITEM("interactive", - PyLong_FromLong(config->interactive)); - SET_ITEM("optimization_level", - PyLong_FromLong(config->optimization_level)); - SET_ITEM("parser_debug", - PyLong_FromLong(config->parser_debug)); - SET_ITEM("write_bytecode", - PyLong_FromLong(config->write_bytecode)); - SET_ITEM("verbose", - PyLong_FromLong(config->verbose)); - SET_ITEM("quiet", - PyLong_FromLong(config->quiet)); - SET_ITEM("user_site_directory", - PyLong_FromLong(config->user_site_directory)); - SET_ITEM("buffered_stdio", - PyLong_FromLong(config->buffered_stdio)); - SET_ITEM("stdio_encoding", - FROM_STRING(config->stdio_encoding)); - SET_ITEM("stdio_errors", - FROM_STRING(config->stdio_errors)); -#ifdef MS_WINDOWS - SET_ITEM("legacy_windows_fs_encoding", - PyLong_FromLong(config->legacy_windows_fs_encoding)); - SET_ITEM("legacy_windows_stdio", - PyLong_FromLong(config->legacy_windows_stdio)); -#endif - SET_ITEM("_install_importlib", - PyLong_FromLong(config->_install_importlib)); - SET_ITEM("_check_hash_pycs_mode", - FROM_STRING(config->_check_hash_pycs_mode)); - SET_ITEM("_frozen", - PyLong_FromLong(config->_frozen)); - - return dict; - -fail: - Py_DECREF(dict); - return NULL; - -#undef FROM_STRING -#undef FROM_WSTRING -#undef SET_ITEM + return _PyCoreConfig_AsDict(config); } diff --git a/Python/coreconfig.c b/Python/coreconfig.c index b21e9344cd..b6fc33c3c9 100644 --- a/Python/coreconfig.c +++ b/Python/coreconfig.c @@ -1358,3 +1358,155 @@ _PyCoreConfig_Read(_PyCoreConfig *config) return _Py_INIT_OK(); } + + +PyObject * +_PyCoreConfig_AsDict(const _PyCoreConfig *config) +{ + PyObject *dict, *obj; + + dict = PyDict_New(); + if (dict == NULL) { + return NULL; + } + +#define FROM_STRING(STR) \ + ((STR != NULL) ? \ + PyUnicode_FromString(STR) \ + : (Py_INCREF(Py_None), Py_None)) +#define FROM_WSTRING(STR) \ + ((STR != NULL) ? \ + PyUnicode_FromWideChar(STR, -1) \ + : (Py_INCREF(Py_None), Py_None)) +#define SET_ITEM(KEY, EXPR) \ + do { \ + obj = (EXPR); \ + if (obj == NULL) { \ + return NULL; \ + } \ + int res = PyDict_SetItemString(dict, (KEY), obj); \ + Py_DECREF(obj); \ + if (res < 0) { \ + goto fail; \ + } \ + } while (0) + + SET_ITEM("install_signal_handlers", + PyLong_FromLong(config->install_signal_handlers)); + SET_ITEM("use_environment", + PyLong_FromLong(config->use_environment)); + SET_ITEM("use_hash_seed", + PyLong_FromLong(config->use_hash_seed)); + SET_ITEM("hash_seed", + PyLong_FromUnsignedLong(config->hash_seed)); + SET_ITEM("allocator", + FROM_STRING(config->allocator)); + SET_ITEM("dev_mode", + PyLong_FromLong(config->dev_mode)); + SET_ITEM("faulthandler", + PyLong_FromLong(config->faulthandler)); + SET_ITEM("tracemalloc", + PyLong_FromLong(config->tracemalloc)); + SET_ITEM("import_time", + PyLong_FromLong(config->import_time)); + SET_ITEM("show_ref_count", + PyLong_FromLong(config->show_ref_count)); + SET_ITEM("show_alloc_count", + PyLong_FromLong(config->show_alloc_count)); + SET_ITEM("dump_refs", + PyLong_FromLong(config->dump_refs)); + SET_ITEM("malloc_stats", + PyLong_FromLong(config->malloc_stats)); + SET_ITEM("coerce_c_locale", + PyLong_FromLong(config->coerce_c_locale)); + SET_ITEM("coerce_c_locale_warn", + PyLong_FromLong(config->coerce_c_locale_warn)); + SET_ITEM("filesystem_encoding", + FROM_STRING(config->filesystem_encoding)); + SET_ITEM("filesystem_errors", + FROM_STRING(config->filesystem_errors)); + SET_ITEM("stdio_encoding", + FROM_STRING(config->stdio_encoding)); + SET_ITEM("utf8_mode", + PyLong_FromLong(config->utf8_mode)); + SET_ITEM("pycache_prefix", + FROM_WSTRING(config->pycache_prefix)); + SET_ITEM("program_name", + FROM_WSTRING(config->program_name)); + SET_ITEM("argv", + _Py_wstrlist_as_pylist(config->argc, config->argv)); + SET_ITEM("program", + FROM_WSTRING(config->program)); + SET_ITEM("warnoptions", + _Py_wstrlist_as_pylist(config->nwarnoption, config->warnoptions)); + SET_ITEM("module_search_path_env", + FROM_WSTRING(config->module_search_path_env)); + SET_ITEM("home", + FROM_WSTRING(config->home)); + SET_ITEM("module_search_paths", + _Py_wstrlist_as_pylist(config->nmodule_search_path, config->module_search_paths)); + SET_ITEM("executable", + FROM_WSTRING(config->executable)); + SET_ITEM("prefix", + FROM_WSTRING(config->prefix)); + SET_ITEM("base_prefix", + FROM_WSTRING(config->base_prefix)); + SET_ITEM("exec_prefix", + FROM_WSTRING(config->exec_prefix)); + SET_ITEM("base_exec_prefix", + FROM_WSTRING(config->base_exec_prefix)); +#ifdef MS_WINDOWS + SET_ITEM("dll_path", + FROM_WSTRING(config->dll_path)); +#endif + SET_ITEM("isolated", + PyLong_FromLong(config->isolated)); + SET_ITEM("site_import", + PyLong_FromLong(config->site_import)); + SET_ITEM("bytes_warning", + PyLong_FromLong(config->bytes_warning)); + SET_ITEM("inspect", + PyLong_FromLong(config->inspect)); + SET_ITEM("interactive", + PyLong_FromLong(config->interactive)); + SET_ITEM("optimization_level", + PyLong_FromLong(config->optimization_level)); + SET_ITEM("parser_debug", + PyLong_FromLong(config->parser_debug)); + SET_ITEM("write_bytecode", + PyLong_FromLong(config->write_bytecode)); + SET_ITEM("verbose", + PyLong_FromLong(config->verbose)); + SET_ITEM("quiet", + PyLong_FromLong(config->quiet)); + SET_ITEM("user_site_directory", + PyLong_FromLong(config->user_site_directory)); + SET_ITEM("buffered_stdio", + PyLong_FromLong(config->buffered_stdio)); + SET_ITEM("stdio_encoding", + FROM_STRING(config->stdio_encoding)); + SET_ITEM("stdio_errors", + FROM_STRING(config->stdio_errors)); +#ifdef MS_WINDOWS + SET_ITEM("legacy_windows_fs_encoding", + PyLong_FromLong(config->legacy_windows_fs_encoding)); + SET_ITEM("legacy_windows_stdio", + PyLong_FromLong(config->legacy_windows_stdio)); +#endif + SET_ITEM("_install_importlib", + PyLong_FromLong(config->_install_importlib)); + SET_ITEM("_check_hash_pycs_mode", + FROM_STRING(config->_check_hash_pycs_mode)); + SET_ITEM("_frozen", + PyLong_FromLong(config->_frozen)); + + return dict; + +fail: + Py_DECREF(dict); + return NULL; + +#undef FROM_STRING +#undef FROM_WSTRING +#undef SET_ITEM +} -- 2.40.0