Skip to content

Commit 5ed6995

Browse files
authored
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.
1 parent f1b9ad3 commit 5ed6995

File tree

4 files changed

+164
-149
lines changed

4 files changed

+164
-149
lines changed

Include/coreconfig.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -358,9 +358,10 @@ PyAPI_FUNC(int) _PyCoreConfig_GetEnvDup(
358358
wchar_t **dest,
359359
wchar_t *wname,
360360
char *name);
361-
#endif
362-
363361

362+
/* Used by _testcapi.get_coreconfig() */
363+
PyAPI_FUNC(PyObject *) _PyCoreConfig_AsDict(const _PyCoreConfig *config);
364+
#endif
364365

365366
#ifdef __cplusplus
366367
}

Include/internal/pycore_pathconfig.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@
44
extern "C" {
55
#endif
66

7+
#ifndef Py_BUILD_CORE
8+
# error "Py_BUILD_CORE must be defined to include this header"
9+
#endif
10+
711
PyAPI_FUNC(void) _Py_wstrlist_clear(
812
int len,
913
wchar_t **list);

Modules/_testcapimodule.c

Lines changed: 5 additions & 147 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
#include "Python.h"
1111
#include "datetime.h"
1212
#include "marshal.h"
13-
#include "pycore_pathconfig.h"
1413
#include "pythread.h"
1514
#include "structmember.h"
1615
#include <float.h>
@@ -24,6 +23,10 @@
2423
#include <sys/wait.h> /* For W_STOPCODE */
2524
#endif
2625

26+
#ifdef Py_BUILD_CORE
27+
# error "_testcapi must test the public Python C API, not CPython internal C API"
28+
#endif
29+
2730
static PyObject *TestError; /* set to exception object in init */
2831

2932
/* Raise TestError with test_name + ": " + msg, and return NULL. */
@@ -4670,152 +4673,7 @@ get_coreconfig(PyObject *self, PyObject *Py_UNUSED(args))
46704673
{
46714674
PyInterpreterState *interp = _PyInterpreterState_Get();
46724675
const _PyCoreConfig *config = &interp->core_config;
4673-
PyObject *dict, *obj;
4674-
4675-
dict = PyDict_New();
4676-
if (dict == NULL) {
4677-
return NULL;
4678-
}
4679-
4680-
#define FROM_STRING(STR) \
4681-
((STR != NULL) ? \
4682-
PyUnicode_FromString(STR) \
4683-
: (Py_INCREF(Py_None), Py_None))
4684-
#define FROM_WSTRING(STR) \
4685-
((STR != NULL) ? \
4686-
PyUnicode_FromWideChar(STR, -1) \
4687-
: (Py_INCREF(Py_None), Py_None))
4688-
#define SET_ITEM(KEY, EXPR) \
4689-
do { \
4690-
obj = (EXPR); \
4691-
if (obj == NULL) { \
4692-
return NULL; \
4693-
} \
4694-
int res = PyDict_SetItemString(dict, (KEY), obj); \
4695-
Py_DECREF(obj); \
4696-
if (res < 0) { \
4697-
goto fail; \
4698-
} \
4699-
} while (0)
4700-
4701-
SET_ITEM("install_signal_handlers",
4702-
PyLong_FromLong(config->install_signal_handlers));
4703-
SET_ITEM("use_environment",
4704-
PyLong_FromLong(config->use_environment));
4705-
SET_ITEM("use_hash_seed",
4706-
PyLong_FromLong(config->use_hash_seed));
4707-
SET_ITEM("hash_seed",
4708-
PyLong_FromUnsignedLong(config->hash_seed));
4709-
SET_ITEM("allocator",
4710-
FROM_STRING(config->allocator));
4711-
SET_ITEM("dev_mode",
4712-
PyLong_FromLong(config->dev_mode));
4713-
SET_ITEM("faulthandler",
4714-
PyLong_FromLong(config->faulthandler));
4715-
SET_ITEM("tracemalloc",
4716-
PyLong_FromLong(config->tracemalloc));
4717-
SET_ITEM("import_time",
4718-
PyLong_FromLong(config->import_time));
4719-
SET_ITEM("show_ref_count",
4720-
PyLong_FromLong(config->show_ref_count));
4721-
SET_ITEM("show_alloc_count",
4722-
PyLong_FromLong(config->show_alloc_count));
4723-
SET_ITEM("dump_refs",
4724-
PyLong_FromLong(config->dump_refs));
4725-
SET_ITEM("malloc_stats",
4726-
PyLong_FromLong(config->malloc_stats));
4727-
SET_ITEM("coerce_c_locale",
4728-
PyLong_FromLong(config->coerce_c_locale));
4729-
SET_ITEM("coerce_c_locale_warn",
4730-
PyLong_FromLong(config->coerce_c_locale_warn));
4731-
SET_ITEM("filesystem_encoding",
4732-
FROM_STRING(config->filesystem_encoding));
4733-
SET_ITEM("filesystem_errors",
4734-
FROM_STRING(config->filesystem_errors));
4735-
SET_ITEM("stdio_encoding",
4736-
FROM_STRING(config->stdio_encoding));
4737-
SET_ITEM("utf8_mode",
4738-
PyLong_FromLong(config->utf8_mode));
4739-
SET_ITEM("pycache_prefix",
4740-
FROM_WSTRING(config->pycache_prefix));
4741-
SET_ITEM("program_name",
4742-
FROM_WSTRING(config->program_name));
4743-
SET_ITEM("argv",
4744-
_Py_wstrlist_as_pylist(config->argc, config->argv));
4745-
SET_ITEM("program",
4746-
FROM_WSTRING(config->program));
4747-
SET_ITEM("warnoptions",
4748-
_Py_wstrlist_as_pylist(config->nwarnoption, config->warnoptions));
4749-
SET_ITEM("module_search_path_env",
4750-
FROM_WSTRING(config->module_search_path_env));
4751-
SET_ITEM("home",
4752-
FROM_WSTRING(config->home));
4753-
SET_ITEM("module_search_paths",
4754-
_Py_wstrlist_as_pylist(config->nmodule_search_path, config->module_search_paths));
4755-
SET_ITEM("executable",
4756-
FROM_WSTRING(config->executable));
4757-
SET_ITEM("prefix",
4758-
FROM_WSTRING(config->prefix));
4759-
SET_ITEM("base_prefix",
4760-
FROM_WSTRING(config->base_prefix));
4761-
SET_ITEM("exec_prefix",
4762-
FROM_WSTRING(config->exec_prefix));
4763-
SET_ITEM("base_exec_prefix",
4764-
FROM_WSTRING(config->base_exec_prefix));
4765-
#ifdef MS_WINDOWS
4766-
SET_ITEM("dll_path",
4767-
FROM_WSTRING(config->dll_path));
4768-
#endif
4769-
SET_ITEM("isolated",
4770-
PyLong_FromLong(config->isolated));
4771-
SET_ITEM("site_import",
4772-
PyLong_FromLong(config->site_import));
4773-
SET_ITEM("bytes_warning",
4774-
PyLong_FromLong(config->bytes_warning));
4775-
SET_ITEM("inspect",
4776-
PyLong_FromLong(config->inspect));
4777-
SET_ITEM("interactive",
4778-
PyLong_FromLong(config->interactive));
4779-
SET_ITEM("optimization_level",
4780-
PyLong_FromLong(config->optimization_level));
4781-
SET_ITEM("parser_debug",
4782-
PyLong_FromLong(config->parser_debug));
4783-
SET_ITEM("write_bytecode",
4784-
PyLong_FromLong(config->write_bytecode));
4785-
SET_ITEM("verbose",
4786-
PyLong_FromLong(config->verbose));
4787-
SET_ITEM("quiet",
4788-
PyLong_FromLong(config->quiet));
4789-
SET_ITEM("user_site_directory",
4790-
PyLong_FromLong(config->user_site_directory));
4791-
SET_ITEM("buffered_stdio",
4792-
PyLong_FromLong(config->buffered_stdio));
4793-
SET_ITEM("stdio_encoding",
4794-
FROM_STRING(config->stdio_encoding));
4795-
SET_ITEM("stdio_errors",
4796-
FROM_STRING(config->stdio_errors));
4797-
#ifdef MS_WINDOWS
4798-
SET_ITEM("legacy_windows_fs_encoding",
4799-
PyLong_FromLong(config->legacy_windows_fs_encoding));
4800-
SET_ITEM("legacy_windows_stdio",
4801-
PyLong_FromLong(config->legacy_windows_stdio));
4802-
#endif
4803-
SET_ITEM("_install_importlib",
4804-
PyLong_FromLong(config->_install_importlib));
4805-
SET_ITEM("_check_hash_pycs_mode",
4806-
FROM_STRING(config->_check_hash_pycs_mode));
4807-
SET_ITEM("_frozen",
4808-
PyLong_FromLong(config->_frozen));
4809-
4810-
return dict;
4811-
4812-
fail:
4813-
Py_DECREF(dict);
4814-
return NULL;
4815-
4816-
#undef FROM_STRING
4817-
#undef FROM_WSTRING
4818-
#undef SET_ITEM
4676+
return _PyCoreConfig_AsDict(config);
48194677
}
48204678

48214679

Python/coreconfig.c

Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1358,3 +1358,155 @@ _PyCoreConfig_Read(_PyCoreConfig *config)
13581358

13591359
return _Py_INIT_OK();
13601360
}
1361+
1362+
1363+
PyObject *
1364+
_PyCoreConfig_AsDict(const _PyCoreConfig *config)
1365+
{
1366+
PyObject *dict, *obj;
1367+
1368+
dict = PyDict_New();
1369+
if (dict == NULL) {
1370+
return NULL;
1371+
}
1372+
1373+
#define FROM_STRING(STR) \
1374+
((STR != NULL) ? \
1375+
PyUnicode_FromString(STR) \
1376+
: (Py_INCREF(Py_None), Py_None))
1377+
#define FROM_WSTRING(STR) \
1378+
((STR != NULL) ? \
1379+
PyUnicode_FromWideChar(STR, -1) \
1380+
: (Py_INCREF(Py_None), Py_None))
1381+
#define SET_ITEM(KEY, EXPR) \
1382+
do { \
1383+
obj = (EXPR); \
1384+
if (obj == NULL) { \
1385+
return NULL; \
1386+
} \
1387+
int res = PyDict_SetItemString(dict, (KEY), obj); \
1388+
Py_DECREF(obj); \
1389+
if (res < 0) { \
1390+
goto fail; \
1391+
} \
1392+
} while (0)
1393+
1394+
SET_ITEM("install_signal_handlers",
1395+
PyLong_FromLong(config->install_signal_handlers));
1396+
SET_ITEM("use_environment",
1397+
PyLong_FromLong(config->use_environment));
1398+
SET_ITEM("use_hash_seed",
1399+
PyLong_FromLong(config->use_hash_seed));
1400+
SET_ITEM("hash_seed",
1401+
PyLong_FromUnsignedLong(config->hash_seed));
1402+
SET_ITEM("allocator",
1403+
FROM_STRING(config->allocator));
1404+
SET_ITEM("dev_mode",
1405+
PyLong_FromLong(config->dev_mode));
1406+
SET_ITEM("faulthandler",
1407+
PyLong_FromLong(config->faulthandler));
1408+
SET_ITEM("tracemalloc",
1409+
PyLong_FromLong(config->tracemalloc));
1410+
SET_ITEM("import_time",
1411+
PyLong_FromLong(config->import_time));
1412+
SET_ITEM("show_ref_count",
1413+
PyLong_FromLong(config->show_ref_count));
1414+
SET_ITEM("show_alloc_count",
1415+
PyLong_FromLong(config->show_alloc_count));
1416+
SET_ITEM("dump_refs",
1417+
PyLong_FromLong(config->dump_refs));
1418+
SET_ITEM("malloc_stats",
1419+
PyLong_FromLong(config->malloc_stats));
1420+
SET_ITEM("coerce_c_locale",
1421+
PyLong_FromLong(config->coerce_c_locale));
1422+
SET_ITEM("coerce_c_locale_warn",
1423+
PyLong_FromLong(config->coerce_c_locale_warn));
1424+
SET_ITEM("filesystem_encoding",
1425+
FROM_STRING(config->filesystem_encoding));
1426+
SET_ITEM("filesystem_errors",
1427+
FROM_STRING(config->filesystem_errors));
1428+
SET_ITEM("stdio_encoding",
1429+
FROM_STRING(config->stdio_encoding));
1430+
SET_ITEM("utf8_mode",
1431+
PyLong_FromLong(config->utf8_mode));
1432+
SET_ITEM("pycache_prefix",
1433+
FROM_WSTRING(config->pycache_prefix));
1434+
SET_ITEM("program_name",
1435+
FROM_WSTRING(config->program_name));
1436+
SET_ITEM("argv",
1437+
_Py_wstrlist_as_pylist(config->argc, config->argv));
1438+
SET_ITEM("program",
1439+
FROM_WSTRING(config->program));
1440+
SET_ITEM("warnoptions",
1441+
_Py_wstrlist_as_pylist(config->nwarnoption, config->warnoptions));
1442+
SET_ITEM("module_search_path_env",
1443+
FROM_WSTRING(config->module_search_path_env));
1444+
SET_ITEM("home",
1445+
FROM_WSTRING(config->home));
1446+
SET_ITEM("module_search_paths",
1447+
_Py_wstrlist_as_pylist(config->nmodule_search_path, config->module_search_paths));
1448+
SET_ITEM("executable",
1449+
FROM_WSTRING(config->executable));
1450+
SET_ITEM("prefix",
1451+
FROM_WSTRING(config->prefix));
1452+
SET_ITEM("base_prefix",
1453+
FROM_WSTRING(config->base_prefix));
1454+
SET_ITEM("exec_prefix",
1455+
FROM_WSTRING(config->exec_prefix));
1456+
SET_ITEM("base_exec_prefix",
1457+
FROM_WSTRING(config->base_exec_prefix));
1458+
#ifdef MS_WINDOWS
1459+
SET_ITEM("dll_path",
1460+
FROM_WSTRING(config->dll_path));
1461+
#endif
1462+
SET_ITEM("isolated",
1463+
PyLong_FromLong(config->isolated));
1464+
SET_ITEM("site_import",
1465+
PyLong_FromLong(config->site_import));
1466+
SET_ITEM("bytes_warning",
1467+
PyLong_FromLong(config->bytes_warning));
1468+
SET_ITEM("inspect",
1469+
PyLong_FromLong(config->inspect));
1470+
SET_ITEM("interactive",
1471+
PyLong_FromLong(config->interactive));
1472+
SET_ITEM("optimization_level",
1473+
PyLong_FromLong(config->optimization_level));
1474+
SET_ITEM("parser_debug",
1475+
PyLong_FromLong(config->parser_debug));
1476+
SET_ITEM("write_bytecode",
1477+
PyLong_FromLong(config->write_bytecode));
1478+
SET_ITEM("verbose",
1479+
PyLong_FromLong(config->verbose));
1480+
SET_ITEM("quiet",
1481+
PyLong_FromLong(config->quiet));
1482+
SET_ITEM("user_site_directory",
1483+
PyLong_FromLong(config->user_site_directory));
1484+
SET_ITEM("buffered_stdio",
1485+
PyLong_FromLong(config->buffered_stdio));
1486+
SET_ITEM("stdio_encoding",
1487+
FROM_STRING(config->stdio_encoding));
1488+
SET_ITEM("stdio_errors",
1489+
FROM_STRING(config->stdio_errors));
1490+
#ifdef MS_WINDOWS
1491+
SET_ITEM("legacy_windows_fs_encoding",
1492+
PyLong_FromLong(config->legacy_windows_fs_encoding));
1493+
SET_ITEM("legacy_windows_stdio",
1494+
PyLong_FromLong(config->legacy_windows_stdio));
1495+
#endif
1496+
SET_ITEM("_install_importlib",
1497+
PyLong_FromLong(config->_install_importlib));
1498+
SET_ITEM("_check_hash_pycs_mode",
1499+
FROM_STRING(config->_check_hash_pycs_mode));
1500+
SET_ITEM("_frozen",
1501+
PyLong_FromLong(config->_frozen));
1502+
1503+
return dict;
1504+
1505+
fail:
1506+
Py_DECREF(dict);
1507+
return NULL;
1508+
1509+
#undef FROM_STRING
1510+
#undef FROM_WSTRING
1511+
#undef SET_ITEM
1512+
}

0 commit comments

Comments
 (0)