summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVictor Stinner <vstinner@redhat.com>2019-09-26 13:51:50 (GMT)
committerGitHub <noreply@github.com>2019-09-26 13:51:50 (GMT)
commit12f2f177fc483723406d7917194e7f655a20631b (patch)
treef3e1b4227b37efa25e0ca0a487e0d229deba8b95
parent3d984a1fd0c05903268542a216fc496074b2e6da (diff)
downloadcpython-12f2f177fc483723406d7917194e7f655a20631b.zip
cpython-12f2f177fc483723406d7917194e7f655a20631b.tar.gz
cpython-12f2f177fc483723406d7917194e7f655a20631b.tar.bz2
bpo-38234: Py_Initialize() sets global path configuration (GH-16421)
* Py_InitializeFromConfig() now writes PyConfig path configuration to the global path configuration (_Py_path_config). * Add test_embed.test_get_pathconfig(). * Fix typo in _PyWideStringList_Join().
-rw-r--r--Include/internal/pycore_pathconfig.h2
-rw-r--r--Lib/test/test_embed.py38
-rw-r--r--Python/pathconfig.c29
-rw-r--r--Python/pylifecycle.c4
4 files changed, 63 insertions, 10 deletions
diff --git a/Include/internal/pycore_pathconfig.h b/Include/internal/pycore_pathconfig.h
index b5d1144..ce75cce 100644
--- a/Include/internal/pycore_pathconfig.h
+++ b/Include/internal/pycore_pathconfig.h
@@ -66,7 +66,7 @@ extern int _Py_FindEnvConfigValue(
extern wchar_t* _Py_GetDLLPath(void);
#endif
-extern PyStatus _PyPathConfig_Init(void);
+extern PyStatus _PyConfig_WritePathConfig(const PyConfig *config);
extern void _Py_DumpPathConfig(PyThreadState *tstate);
#ifdef __cplusplus
diff --git a/Lib/test/test_embed.py b/Lib/test/test_embed.py
index 92b5136..ab086e2 100644
--- a/Lib/test/test_embed.py
+++ b/Lib/test/test_embed.py
@@ -1230,6 +1230,44 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase):
api=API_COMPAT, env=env,
ignore_stderr=True, cwd=tmpdir)
+ def test_global_pathconfig(self):
+ # Test C API functions getting the path configuration:
+ #
+ # - Py_GetExecPrefix()
+ # - Py_GetPath()
+ # - Py_GetPrefix()
+ # - Py_GetProgramFullPath()
+ # - Py_GetProgramName()
+ # - Py_GetPythonHome()
+ #
+ # The global path configuration (_Py_path_config) must be a copy
+ # of the path configuration of PyInterpreter.config (PyConfig).
+ ctypes = support.import_module('ctypes')
+ _testinternalcapi = support.import_module('_testinternalcapi')
+
+ def get_func(name):
+ func = getattr(ctypes.pythonapi, name)
+ func.argtypes = ()
+ func.restype = ctypes.c_wchar_p
+ return func
+
+ Py_GetPath = get_func('Py_GetPath')
+ Py_GetPrefix = get_func('Py_GetPrefix')
+ Py_GetExecPrefix = get_func('Py_GetExecPrefix')
+ Py_GetProgramName = get_func('Py_GetProgramName')
+ Py_GetProgramFullPath = get_func('Py_GetProgramFullPath')
+ Py_GetPythonHome = get_func('Py_GetPythonHome')
+
+ config = _testinternalcapi.get_configs()['config']
+
+ self.assertEqual(Py_GetPath().split(os.path.pathsep),
+ config['module_search_paths'])
+ self.assertEqual(Py_GetPrefix(), config['prefix'])
+ self.assertEqual(Py_GetExecPrefix(), config['exec_prefix'])
+ self.assertEqual(Py_GetProgramName(), config['program_name'])
+ self.assertEqual(Py_GetProgramFullPath(), config['executable'])
+ self.assertEqual(Py_GetPythonHome(), config['home'])
+
class AuditingTests(EmbeddingTestsMixin, unittest.TestCase):
def test_open_code_hook(self):
diff --git a/Python/pathconfig.c b/Python/pathconfig.c
index f4e1498..8126145 100644
--- a/Python/pathconfig.c
+++ b/Python/pathconfig.c
@@ -133,7 +133,7 @@ _PyWideStringList_Join(const PyWideStringList *list, wchar_t sep)
for (Py_ssize_t i=0; i < list->length; i++) {
wchar_t *path = list->items[i];
if (i != 0) {
- *str++ = SEP;
+ *str++ = sep;
}
len = wcslen(path);
memcpy(str, path, len * sizeof(wchar_t));
@@ -145,11 +145,11 @@ _PyWideStringList_Join(const PyWideStringList *list, wchar_t sep)
}
+#ifdef MS_WINDOWS
/* Initialize _Py_dll_path on Windows. Do nothing on other platforms. */
-PyStatus
-_PyPathConfig_Init(void)
+static PyStatus
+_PyPathConfig_InitDLLPath(void)
{
-#ifdef MS_WINDOWS
if (_Py_dll_path == NULL) {
/* Already set: nothing to do */
return _PyStatus_OK();
@@ -165,9 +165,9 @@ _PyPathConfig_Init(void)
if (_Py_dll_path == NULL) {
return _PyStatus_NO_MEMORY();
}
-#endif
return _PyStatus_OK();
}
+#endif
static PyStatus
@@ -217,6 +217,20 @@ done:
}
+PyStatus
+_PyConfig_WritePathConfig(const PyConfig *config)
+{
+#ifdef MS_WINDOWS
+ PyStatus status = _PyPathConfig_InitDLLPath();
+ if (_PyStatus_EXCEPTION(status)) {
+ return status;
+ }
+#endif
+
+ return pathconfig_set_from_config(&_Py_path_config, config);
+}
+
+
static PyStatus
config_init_module_search_paths(PyConfig *config, _PyPathConfig *pathconfig)
{
@@ -441,11 +455,12 @@ pathconfig_global_init(void)
{
PyStatus status;
- /* Initialize _Py_dll_path if needed */
- status = _PyPathConfig_Init();
+#ifdef MS_WINDOWS
+ status = _PyPathConfig_InitDLLPath();
if (_PyStatus_EXCEPTION(status)) {
Py_ExitStatusException(status);
}
+#endif
if (_Py_path_config.module_search_path == NULL) {
status = pathconfig_global_read(&_Py_path_config);
diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c
index e5b6283..eed583a 100644
--- a/Python/pylifecycle.c
+++ b/Python/pylifecycle.c
@@ -475,7 +475,7 @@ pyinit_core_reconfigure(_PyRuntimeState *runtime,
config = &interp->config;
if (config->_install_importlib) {
- status = _PyPathConfig_Init();
+ status = _PyConfig_WritePathConfig(config);
if (_PyStatus_EXCEPTION(status)) {
return status;
}
@@ -646,7 +646,7 @@ pycore_init_import_warnings(PyThreadState *tstate, PyObject *sysmod)
}
if (config->_install_importlib) {
- status = _PyPathConfig_Init();
+ status = _PyConfig_WritePathConfig(config);
if (_PyStatus_EXCEPTION(status)) {
return status;
}