Commit 1075d168 authored by Victor Stinner's avatar Victor Stinner Committed by GitHub

bpo-36301: Add _Py_GetConfigsAsDict() function (GH-12540)

* Add _Py_GetConfigsAsDict() function to get all configurations as a
  dict.
* dump_config() of _testembed.c now dumps preconfig as a separated
  key: call _Py_GetConfigsAsDict().
* Make _PyMainInterpreterConfig_AsDict() private.
parent 91759d98
...@@ -400,8 +400,7 @@ typedef struct { ...@@ -400,8 +400,7 @@ typedef struct {
/* --- Function used for testing ---------------------------------- */ /* --- Function used for testing ---------------------------------- */
PyAPI_FUNC(PyObject *) _Py_GetGlobalVariablesAsDict(void); PyAPI_FUNC(PyObject*) _Py_GetConfigsAsDict(void);
PyAPI_FUNC(PyObject *) _PyCoreConfig_AsDict(const _PyCoreConfig *config);
#ifdef __cplusplus #ifdef __cplusplus
} }
......
...@@ -33,9 +33,6 @@ PyAPI_FUNC(void) _PyMainInterpreterConfig_Clear(_PyMainInterpreterConfig *); ...@@ -33,9 +33,6 @@ PyAPI_FUNC(void) _PyMainInterpreterConfig_Clear(_PyMainInterpreterConfig *);
PyAPI_FUNC(int) _PyMainInterpreterConfig_Copy( PyAPI_FUNC(int) _PyMainInterpreterConfig_Copy(
_PyMainInterpreterConfig *config, _PyMainInterpreterConfig *config,
const _PyMainInterpreterConfig *config2); const _PyMainInterpreterConfig *config2);
/* Used by _testcapi.get_main_config() */
PyAPI_FUNC(PyObject*) _PyMainInterpreterConfig_AsDict(
const _PyMainInterpreterConfig *config);
PyAPI_FUNC(_PyInitError) _Py_InitializeMainInterpreter( PyAPI_FUNC(_PyInitError) _Py_InitializeMainInterpreter(
PyInterpreterState *interp, PyInterpreterState *interp,
......
...@@ -90,8 +90,7 @@ PyAPI_FUNC(void) _Py_get_env_flag(_PyPreConfig *config, ...@@ -90,8 +90,7 @@ PyAPI_FUNC(void) _Py_get_env_flag(_PyPreConfig *config,
PyAPI_FUNC(_PyInitError) _PyPreConfig_Read(_PyPreConfig *config, PyAPI_FUNC(_PyInitError) _PyPreConfig_Read(_PyPreConfig *config,
const _PyArgv *args, const _PyArgv *args,
const _PyCoreConfig *coreconfig); const _PyCoreConfig *coreconfig);
PyAPI_FUNC(int) _PyPreConfig_AsDict(const _PyPreConfig *config, PyAPI_FUNC(PyObject*) _PyPreConfig_AsDict(const _PyPreConfig *config);
PyObject *dict);
PyAPI_FUNC(_PyInitError) _PyPreConfig_ReadFromArgv(_PyPreConfig *config, PyAPI_FUNC(_PyInitError) _PyPreConfig_ReadFromArgv(_PyPreConfig *config,
const _PyArgv *args); const _PyArgv *args);
PyAPI_FUNC(_PyInitError) _PyPreConfig_Write(_PyPreConfig *config); PyAPI_FUNC(_PyInitError) _PyPreConfig_Write(_PyPreConfig *config);
...@@ -121,6 +120,11 @@ PyAPI_FUNC(_PyInitError) _PyCoreConfig_ReadFromArgv(_PyCoreConfig *config, ...@@ -121,6 +120,11 @@ PyAPI_FUNC(_PyInitError) _PyCoreConfig_ReadFromArgv(_PyCoreConfig *config,
const _PyArgv *args); const _PyArgv *args);
PyAPI_FUNC(_PyInitError) _PyCoreConfig_Write(const _PyCoreConfig *config); PyAPI_FUNC(_PyInitError) _PyCoreConfig_Write(const _PyCoreConfig *config);
/* --- _PyMainInterpreterConfig ----------------------------------- */
PyAPI_FUNC(PyObject*) _PyMainInterpreterConfig_AsDict(
const _PyMainInterpreterConfig *config);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
......
...@@ -598,18 +598,15 @@ def collect_get_config(info_add): ...@@ -598,18 +598,15 @@ def collect_get_config(info_add):
# Dump global configuration variables, _PyCoreConfig # Dump global configuration variables, _PyCoreConfig
# and _PyMainInterpreterConfig # and _PyMainInterpreterConfig
try: try:
from _testcapi import get_global_config, get_core_config, get_main_config from _testcapi import get_configs
except ImportError: except ImportError:
return return
for prefix, get_config_func in ( all_configs = get_configs()
('global_config', get_global_config), for config_type in sorted(all_configs):
('core_config', get_core_config), config = all_configs[config_type]
('main_config', get_main_config),
):
config = get_config_func()
for key in sorted(config): for key in sorted(config):
info_add('%s[%s]' % (prefix, key), repr(config[key])) info_add('%s[%s]' % (config_type, key), repr(config[key]))
def collect_subprocess(info_add): def collect_subprocess(info_add):
......
This diff is collapsed.
...@@ -4675,27 +4675,9 @@ decode_locale_ex(PyObject *self, PyObject *args) ...@@ -4675,27 +4675,9 @@ decode_locale_ex(PyObject *self, PyObject *args)
static PyObject * static PyObject *
get_global_config(PyObject *self, PyObject *Py_UNUSED(args)) get_configs(PyObject *self, PyObject *Py_UNUSED(args))
{ {
return _Py_GetGlobalVariablesAsDict(); return _Py_GetConfigsAsDict();
}
static PyObject *
get_core_config(PyObject *self, PyObject *Py_UNUSED(args))
{
PyInterpreterState *interp = _PyInterpreterState_Get();
const _PyCoreConfig *config = _PyInterpreterState_GetCoreConfig(interp);
return _PyCoreConfig_AsDict(config);
}
static PyObject *
get_main_config(PyObject *self, PyObject *Py_UNUSED(args))
{
PyInterpreterState *interp = _PyInterpreterState_Get();
const _PyMainInterpreterConfig *config = _PyInterpreterState_GetMainConfig(interp);
return _PyMainInterpreterConfig_AsDict(config);
} }
...@@ -4942,9 +4924,7 @@ static PyMethodDef TestMethods[] = { ...@@ -4942,9 +4924,7 @@ static PyMethodDef TestMethods[] = {
{"bad_get", (PyCFunction)(void(*)(void))bad_get, METH_FASTCALL}, {"bad_get", (PyCFunction)(void(*)(void))bad_get, METH_FASTCALL},
{"EncodeLocaleEx", encode_locale_ex, METH_VARARGS}, {"EncodeLocaleEx", encode_locale_ex, METH_VARARGS},
{"DecodeLocaleEx", decode_locale_ex, METH_VARARGS}, {"DecodeLocaleEx", decode_locale_ex, METH_VARARGS},
{"get_global_config", get_global_config, METH_NOARGS}, {"get_configs", get_configs, METH_NOARGS},
{"get_core_config", get_core_config, METH_NOARGS},
{"get_main_config", get_main_config, METH_NOARGS},
#ifdef Py_REF_DEBUG #ifdef Py_REF_DEBUG
{"negative_refcount", negative_refcount, METH_NOARGS}, {"negative_refcount", negative_refcount, METH_NOARGS},
#endif #endif
......
...@@ -301,64 +301,29 @@ static int test_initialize_pymain(void) ...@@ -301,64 +301,29 @@ static int test_initialize_pymain(void)
static int static int
dump_config_impl(void) dump_config_impl(void)
{ {
PyObject *config = NULL; PyObject *config = _Py_GetConfigsAsDict();
PyObject *dict = NULL;
config = PyDict_New();
if (config == NULL) { if (config == NULL) {
goto error; return -1;
}
/* global config */
dict = _Py_GetGlobalVariablesAsDict();
if (dict == NULL) {
goto error;
}
if (PyDict_SetItemString(config, "global_config", dict) < 0) {
goto error;
}
Py_CLEAR(dict);
/* core config */
PyInterpreterState *interp = _PyInterpreterState_Get();
const _PyCoreConfig *core_config = _PyInterpreterState_GetCoreConfig(interp);
dict = _PyCoreConfig_AsDict(core_config);
if (dict == NULL) {
goto error;
}
if (PyDict_SetItemString(config, "core_config", dict) < 0) {
goto error;
}
Py_CLEAR(dict);
/* main config */
const _PyMainInterpreterConfig *main_config = _PyInterpreterState_GetMainConfig(interp);
dict = _PyMainInterpreterConfig_AsDict(main_config);
if (dict == NULL) {
goto error;
}
if (PyDict_SetItemString(config, "main_config", dict) < 0) {
goto error;
} }
Py_CLEAR(dict);
PyObject *res;
PyObject *json = PyImport_ImportModule("json"); PyObject *json = PyImport_ImportModule("json");
PyObject *res = PyObject_CallMethod(json, "dumps", "O", config); if (json) {
res = PyObject_CallMethod(json, "dumps", "O", config);
Py_DECREF(json); Py_DECREF(json);
}
else {
res = NULL;
}
Py_CLEAR(config); Py_CLEAR(config);
if (res == NULL) { if (res == NULL) {
goto error; return -1;
} }
PySys_FormatStdout("%S\n", res); PySys_FormatStdout("%S\n", res);
Py_DECREF(res); Py_DECREF(res);
return 0; return 0;
error:
Py_XDECREF(config);
Py_XDECREF(dict);
return -1;
} }
......
...@@ -131,7 +131,7 @@ int Py_LegacyWindowsStdioFlag = 0; /* Uses FileIO instead of WindowsConsoleIO */ ...@@ -131,7 +131,7 @@ int Py_LegacyWindowsStdioFlag = 0; /* Uses FileIO instead of WindowsConsoleIO */
#endif #endif
PyObject * static PyObject *
_Py_GetGlobalVariablesAsDict(void) _Py_GetGlobalVariablesAsDict(void)
{ {
PyObject *dict, *obj; PyObject *dict, *obj;
...@@ -1563,7 +1563,7 @@ _PyCoreConfig_Write(const _PyCoreConfig *config) ...@@ -1563,7 +1563,7 @@ _PyCoreConfig_Write(const _PyCoreConfig *config)
} }
PyObject * static PyObject *
_PyCoreConfig_AsDict(const _PyCoreConfig *config) _PyCoreConfig_AsDict(const _PyCoreConfig *config)
{ {
PyObject *dict; PyObject *dict;
...@@ -1573,11 +1573,6 @@ _PyCoreConfig_AsDict(const _PyCoreConfig *config) ...@@ -1573,11 +1573,6 @@ _PyCoreConfig_AsDict(const _PyCoreConfig *config)
return NULL; return NULL;
} }
if (_PyPreConfig_AsDict(&config->preconfig, dict) < 0) {
Py_DECREF(dict);
return NULL;
}
#define SET_ITEM(KEY, EXPR) \ #define SET_ITEM(KEY, EXPR) \
do { \ do { \
PyObject *obj = (EXPR); \ PyObject *obj = (EXPR); \
...@@ -2158,3 +2153,67 @@ done: ...@@ -2158,3 +2153,67 @@ done:
cmdline_clear(&cmdline); cmdline_clear(&cmdline);
return err; return err;
} }
PyObject*
_Py_GetConfigsAsDict(void)
{
PyObject *config = NULL;
PyObject *dict = NULL;
config = PyDict_New();
if (config == NULL) {
goto error;
}
/* global config */
dict = _Py_GetGlobalVariablesAsDict();
if (dict == NULL) {
goto error;
}
if (PyDict_SetItemString(config, "global_config", dict) < 0) {
goto error;
}
Py_CLEAR(dict);
/* pre config */
PyInterpreterState *interp = _PyInterpreterState_Get();
const _PyCoreConfig *core_config = _PyInterpreterState_GetCoreConfig(interp);
const _PyPreConfig *pre_config = &core_config->preconfig;
dict = _PyPreConfig_AsDict(pre_config);
if (dict == NULL) {
goto error;
}
if (PyDict_SetItemString(config, "pre_config", dict) < 0) {
goto error;
}
Py_CLEAR(dict);
/* core config */
dict = _PyCoreConfig_AsDict(core_config);
if (dict == NULL) {
goto error;
}
if (PyDict_SetItemString(config, "core_config", dict) < 0) {
goto error;
}
Py_CLEAR(dict);
/* main config */
const _PyMainInterpreterConfig *main_config = _PyInterpreterState_GetMainConfig(interp);
dict = _PyMainInterpreterConfig_AsDict(main_config);
if (dict == NULL) {
goto error;
}
if (PyDict_SetItemString(config, "main_config", dict) < 0) {
goto error;
}
Py_CLEAR(dict);
return config;
error:
Py_XDECREF(config);
Py_XDECREF(dict);
return NULL;
}
...@@ -574,9 +574,16 @@ _PyPreCmdline_SetPreConfig(const _PyPreCmdline *cmdline, _PyPreConfig *config) ...@@ -574,9 +574,16 @@ _PyPreCmdline_SetPreConfig(const _PyPreCmdline *cmdline, _PyPreConfig *config)
} }
int PyObject*
_PyPreConfig_AsDict(const _PyPreConfig *config, PyObject *dict) _PyPreConfig_AsDict(const _PyPreConfig *config)
{ {
PyObject *dict;
dict = PyDict_New();
if (dict == NULL) {
return NULL;
}
#define SET_ITEM(KEY, EXPR) \ #define SET_ITEM(KEY, EXPR) \
do { \ do { \
PyObject *obj = (EXPR); \ PyObject *obj = (EXPR); \
...@@ -608,10 +615,11 @@ _PyPreConfig_AsDict(const _PyPreConfig *config, PyObject *dict) ...@@ -608,10 +615,11 @@ _PyPreConfig_AsDict(const _PyPreConfig *config, PyObject *dict)
#endif #endif
SET_ITEM_INT(dev_mode); SET_ITEM_INT(dev_mode);
SET_ITEM_STR(allocator); SET_ITEM_STR(allocator);
return 0; return dict;
fail: fail:
return -1; Py_DECREF(dict);
return NULL;
#undef FROM_STRING #undef FROM_STRING
#undef SET_ITEM #undef SET_ITEM
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment