bpo-38234: Add test_init_setpath_config() to test_embed (GH-16402)
* Add test_embed.test_init_setpath_config(): test Py_SetPath() with PyConfig. * test_init_setpath() and test_init_setpythonhome() no longer call Py_SetProgramName(), but use the default program name. * _PyPathConfig: isolated, site_import and base_executable fields are now only available on Windows. * If executable is set explicitly in the configuration, ignore calculated base_executable: _PyConfig_InitPathConfig() copies executable to base_executable. * Complete path config documentation.
This commit is contained in:
parent
df69e75edc
commit
8bf39b606e
|
@ -864,29 +864,38 @@ Path Configuration
|
||||||
|
|
||||||
:c:type:`PyConfig` contains multiple fields for the path configuration:
|
:c:type:`PyConfig` contains multiple fields for the path configuration:
|
||||||
|
|
||||||
* Path configuration input fields:
|
* Path configuration inputs:
|
||||||
|
|
||||||
* :c:member:`PyConfig.home`
|
* :c:member:`PyConfig.home`
|
||||||
* :c:member:`PyConfig.pathconfig_warnings`
|
* :c:member:`PyConfig.pathconfig_warnings`
|
||||||
* :c:member:`PyConfig.program_name`
|
* :c:member:`PyConfig.program_name`
|
||||||
* :c:member:`PyConfig.pythonpath_env`
|
* :c:member:`PyConfig.pythonpath_env`
|
||||||
|
* current working directory: to get absolute paths
|
||||||
|
* ``PATH`` environment variable to get the program full path
|
||||||
|
(from :c:member:`PyConfig.program_name`)
|
||||||
|
* ``__PYVENV_LAUNCHER__`` environment variable
|
||||||
|
* (Windows only) Application paths in the registry under
|
||||||
|
"Software\Python\PythonCore\X.Y\PythonPath" of HKEY_CURRENT_USER and
|
||||||
|
HKEY_LOCAL_MACHINE (where X.Y is the Python version).
|
||||||
|
|
||||||
* Path configuration output fields:
|
* Path configuration output fields:
|
||||||
|
|
||||||
|
* :c:member:`PyConfig.base_exec_prefix`
|
||||||
* :c:member:`PyConfig.base_executable`
|
* :c:member:`PyConfig.base_executable`
|
||||||
|
* :c:member:`PyConfig.base_prefix`
|
||||||
* :c:member:`PyConfig.exec_prefix`
|
* :c:member:`PyConfig.exec_prefix`
|
||||||
* :c:member:`PyConfig.executable`
|
* :c:member:`PyConfig.executable`
|
||||||
* :c:member:`PyConfig.prefix`
|
|
||||||
* :c:member:`PyConfig.module_search_paths_set`,
|
* :c:member:`PyConfig.module_search_paths_set`,
|
||||||
:c:member:`PyConfig.module_search_paths`
|
:c:member:`PyConfig.module_search_paths`
|
||||||
|
* :c:member:`PyConfig.prefix`
|
||||||
|
|
||||||
If at least one "output field" is not set, Python computes the path
|
If at least one "output field" is not set, Python calculates the path
|
||||||
configuration to fill unset fields. If
|
configuration to fill unset fields. If
|
||||||
:c:member:`~PyConfig.module_search_paths_set` is equal to 0,
|
:c:member:`~PyConfig.module_search_paths_set` is equal to 0,
|
||||||
:c:member:`~PyConfig.module_search_paths` is overridden and
|
:c:member:`~PyConfig.module_search_paths` is overridden and
|
||||||
:c:member:`~PyConfig.module_search_paths_set` is set to 1.
|
:c:member:`~PyConfig.module_search_paths_set` is set to 1.
|
||||||
|
|
||||||
It is possible to completely ignore the function computing the default
|
It is possible to completely ignore the function calculating the default
|
||||||
path configuration by setting explicitly all path configuration output
|
path configuration by setting explicitly all path configuration output
|
||||||
fields listed above. A string is considered as set even if it is non-empty.
|
fields listed above. A string is considered as set even if it is non-empty.
|
||||||
``module_search_paths`` is considered as set if
|
``module_search_paths`` is considered as set if
|
||||||
|
@ -894,7 +903,7 @@ fields listed above. A string is considered as set even if it is non-empty.
|
||||||
configuration input fields are ignored as well.
|
configuration input fields are ignored as well.
|
||||||
|
|
||||||
Set :c:member:`~PyConfig.pathconfig_warnings` to 0 to suppress warnings when
|
Set :c:member:`~PyConfig.pathconfig_warnings` to 0 to suppress warnings when
|
||||||
computing the path configuration (Unix only, Windows does not log any warning).
|
calculating the path configuration (Unix only, Windows does not log any warning).
|
||||||
|
|
||||||
If :c:member:`~PyConfig.base_prefix` or :c:member:`~PyConfig.base_exec_prefix`
|
If :c:member:`~PyConfig.base_prefix` or :c:member:`~PyConfig.base_exec_prefix`
|
||||||
fields are not set, they inherit their value from :c:member:`~PyConfig.prefix`
|
fields are not set, they inherit their value from :c:member:`~PyConfig.prefix`
|
||||||
|
|
|
@ -19,6 +19,7 @@ typedef struct _PyPathConfig {
|
||||||
wchar_t *program_name;
|
wchar_t *program_name;
|
||||||
/* Set by Py_SetPythonHome() or PYTHONHOME environment variable */
|
/* Set by Py_SetPythonHome() or PYTHONHOME environment variable */
|
||||||
wchar_t *home;
|
wchar_t *home;
|
||||||
|
#ifdef MS_WINDOWS
|
||||||
/* isolated and site_import are used to set Py_IsolatedFlag and
|
/* isolated and site_import are used to set Py_IsolatedFlag and
|
||||||
Py_NoSiteFlag flags on Windows in read_pth_file(). These fields
|
Py_NoSiteFlag flags on Windows in read_pth_file(). These fields
|
||||||
are ignored when their value are equal to -1 (unset). */
|
are ignored when their value are equal to -1 (unset). */
|
||||||
|
@ -26,12 +27,18 @@ typedef struct _PyPathConfig {
|
||||||
int site_import;
|
int site_import;
|
||||||
/* Set when a venv is detected */
|
/* Set when a venv is detected */
|
||||||
wchar_t *base_executable;
|
wchar_t *base_executable;
|
||||||
|
#endif
|
||||||
} _PyPathConfig;
|
} _PyPathConfig;
|
||||||
|
|
||||||
#define _PyPathConfig_INIT \
|
#ifdef MS_WINDOWS
|
||||||
{.module_search_path = NULL, \
|
# define _PyPathConfig_INIT \
|
||||||
.isolated = -1, \
|
{.module_search_path = NULL, \
|
||||||
.site_import = -1}
|
.isolated = -1, \
|
||||||
|
.site_import = -1}
|
||||||
|
#else
|
||||||
|
# define _PyPathConfig_INIT \
|
||||||
|
{.module_search_path = NULL}
|
||||||
|
#endif
|
||||||
/* Note: _PyPathConfig_INIT sets other fields to 0/NULL */
|
/* Note: _PyPathConfig_INIT sets other fields to 0/NULL */
|
||||||
|
|
||||||
PyAPI_DATA(_PyPathConfig) _Py_path_config;
|
PyAPI_DATA(_PyPathConfig) _Py_path_config;
|
||||||
|
|
|
@ -635,16 +635,19 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase):
|
||||||
self.assertEqual(configs['global_config'], expected)
|
self.assertEqual(configs['global_config'], expected)
|
||||||
|
|
||||||
def check_all_configs(self, testname, expected_config=None,
|
def check_all_configs(self, testname, expected_config=None,
|
||||||
expected_preconfig=None, modify_path_cb=None, stderr=None,
|
expected_preconfig=None, modify_path_cb=None,
|
||||||
*, api, env=None, ignore_stderr=False, cwd=None):
|
stderr=None, *, api, preconfig_api=None,
|
||||||
|
env=None, ignore_stderr=False, cwd=None):
|
||||||
new_env = remove_python_envvars()
|
new_env = remove_python_envvars()
|
||||||
if env is not None:
|
if env is not None:
|
||||||
new_env.update(env)
|
new_env.update(env)
|
||||||
env = new_env
|
env = new_env
|
||||||
|
|
||||||
if api == API_ISOLATED:
|
if preconfig_api is None:
|
||||||
|
preconfig_api = api
|
||||||
|
if preconfig_api == API_ISOLATED:
|
||||||
default_preconfig = self.PRE_CONFIG_ISOLATED
|
default_preconfig = self.PRE_CONFIG_ISOLATED
|
||||||
elif api == API_PYTHON:
|
elif preconfig_api == API_PYTHON:
|
||||||
default_preconfig = self.PRE_CONFIG_PYTHON
|
default_preconfig = self.PRE_CONFIG_PYTHON
|
||||||
else:
|
else:
|
||||||
default_preconfig = self.PRE_CONFIG_COMPAT
|
default_preconfig = self.PRE_CONFIG_COMPAT
|
||||||
|
@ -1002,8 +1005,21 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase):
|
||||||
self.check_all_configs("test_init_dont_parse_argv", config, pre_config,
|
self.check_all_configs("test_init_dont_parse_argv", config, pre_config,
|
||||||
api=API_PYTHON)
|
api=API_PYTHON)
|
||||||
|
|
||||||
|
def default_program_name(self, config):
|
||||||
|
if MS_WINDOWS:
|
||||||
|
program_name = 'python'
|
||||||
|
executable = self.test_exe
|
||||||
|
else:
|
||||||
|
program_name = 'python3'
|
||||||
|
executable = shutil.which(program_name) or ''
|
||||||
|
config.update({
|
||||||
|
'program_name': program_name,
|
||||||
|
'base_executable': executable,
|
||||||
|
'executable': executable,
|
||||||
|
})
|
||||||
|
|
||||||
def test_init_setpath(self):
|
def test_init_setpath(self):
|
||||||
# Test Py_SetProgramName() + Py_SetPath()
|
# Test Py_SetPath()
|
||||||
config = self._get_expected_config()
|
config = self._get_expected_config()
|
||||||
paths = config['config']['module_search_paths']
|
paths = config['config']['module_search_paths']
|
||||||
|
|
||||||
|
@ -1014,11 +1030,38 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase):
|
||||||
'exec_prefix': '',
|
'exec_prefix': '',
|
||||||
'base_exec_prefix': '',
|
'base_exec_prefix': '',
|
||||||
}
|
}
|
||||||
|
self.default_program_name(config)
|
||||||
env = {'TESTPATH': os.path.pathsep.join(paths)}
|
env = {'TESTPATH': os.path.pathsep.join(paths)}
|
||||||
self.check_all_configs("test_init_setpath", config,
|
self.check_all_configs("test_init_setpath", config,
|
||||||
api=API_COMPAT, env=env,
|
api=API_COMPAT, env=env,
|
||||||
ignore_stderr=True)
|
ignore_stderr=True)
|
||||||
|
|
||||||
|
def test_init_setpath_config(self):
|
||||||
|
# Test Py_SetPath() with PyConfig
|
||||||
|
config = self._get_expected_config()
|
||||||
|
paths = config['config']['module_search_paths']
|
||||||
|
|
||||||
|
config = {
|
||||||
|
# set by Py_SetPath()
|
||||||
|
'module_search_paths': paths,
|
||||||
|
'prefix': '',
|
||||||
|
'base_prefix': '',
|
||||||
|
'exec_prefix': '',
|
||||||
|
'base_exec_prefix': '',
|
||||||
|
# overriden by PyConfig
|
||||||
|
'program_name': 'conf_program_name',
|
||||||
|
'base_executable': 'conf_executable',
|
||||||
|
'executable': 'conf_executable',
|
||||||
|
}
|
||||||
|
env = {'TESTPATH': os.path.pathsep.join(paths)}
|
||||||
|
# Py_SetPath() preinitialized Python using the compat API,
|
||||||
|
# so we need preconfig_api=API_COMPAT.
|
||||||
|
self.check_all_configs("test_init_setpath_config", config,
|
||||||
|
api=API_PYTHON,
|
||||||
|
preconfig_api=API_COMPAT,
|
||||||
|
env=env,
|
||||||
|
ignore_stderr=True)
|
||||||
|
|
||||||
def module_search_paths(self, prefix=None, exec_prefix=None):
|
def module_search_paths(self, prefix=None, exec_prefix=None):
|
||||||
config = self._get_expected_config()
|
config = self._get_expected_config()
|
||||||
if prefix is None:
|
if prefix is None:
|
||||||
|
@ -1067,8 +1110,7 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase):
|
||||||
yield tmpdir
|
yield tmpdir
|
||||||
|
|
||||||
def test_init_setpythonhome(self):
|
def test_init_setpythonhome(self):
|
||||||
# Test Py_SetPythonHome(home) + PYTHONPATH env var
|
# Test Py_SetPythonHome(home) with PYTHONPATH env var
|
||||||
# + Py_SetProgramName()
|
|
||||||
config = self._get_expected_config()
|
config = self._get_expected_config()
|
||||||
paths = config['config']['module_search_paths']
|
paths = config['config']['module_search_paths']
|
||||||
paths_str = os.path.pathsep.join(paths)
|
paths_str = os.path.pathsep.join(paths)
|
||||||
|
@ -1095,7 +1137,8 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase):
|
||||||
'base_exec_prefix': exec_prefix,
|
'base_exec_prefix': exec_prefix,
|
||||||
'pythonpath_env': paths_str,
|
'pythonpath_env': paths_str,
|
||||||
}
|
}
|
||||||
env = {'TESTHOME': home, 'TESTPATH': paths_str}
|
self.default_program_name(config)
|
||||||
|
env = {'TESTHOME': home, 'PYTHONPATH': paths_str}
|
||||||
self.check_all_configs("test_init_setpythonhome", config,
|
self.check_all_configs("test_init_setpythonhome", config,
|
||||||
api=API_COMPAT, env=env)
|
api=API_COMPAT, env=env)
|
||||||
|
|
||||||
|
|
|
@ -1099,11 +1099,11 @@ calculate_free(PyCalculatePath *calculate)
|
||||||
- __PYVENV_LAUNCHER__ environment variable
|
- __PYVENV_LAUNCHER__ environment variable
|
||||||
- GetModuleFileNameW(NULL): fully qualified path of the executable file of
|
- GetModuleFileNameW(NULL): fully qualified path of the executable file of
|
||||||
the current process
|
the current process
|
||||||
- .pth configuration file
|
- ._pth configuration file
|
||||||
- pyvenv.cfg configuration file
|
- pyvenv.cfg configuration file
|
||||||
- Registry key "Software\Python\PythonCore\X.Y\PythonPath"
|
- Registry key "Software\Python\PythonCore\X.Y\PythonPath"
|
||||||
of HKEY_LOCAL_MACHINE and HKEY_CURRENT_USER where X.Y is the Python
|
of HKEY_CURRENT_USER and HKEY_LOCAL_MACHINE where X.Y is the Python
|
||||||
version (major.minor).
|
version.
|
||||||
|
|
||||||
Outputs, 'pathconfig' fields:
|
Outputs, 'pathconfig' fields:
|
||||||
|
|
||||||
|
|
|
@ -1425,8 +1425,6 @@ fail:
|
||||||
|
|
||||||
static int test_init_setpath(void)
|
static int test_init_setpath(void)
|
||||||
{
|
{
|
||||||
Py_SetProgramName(PROGRAM_NAME);
|
|
||||||
|
|
||||||
char *env = getenv("TESTPATH");
|
char *env = getenv("TESTPATH");
|
||||||
if (!env) {
|
if (!env) {
|
||||||
fprintf(stderr, "missing TESTPATH env var\n");
|
fprintf(stderr, "missing TESTPATH env var\n");
|
||||||
|
@ -1448,23 +1446,35 @@ static int test_init_setpath(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int mysetenv(const char *name, const char *value)
|
static int test_init_setpath_config(void)
|
||||||
{
|
{
|
||||||
size_t len = strlen(name) + 1 + strlen(value) + 1;
|
char *env = getenv("TESTPATH");
|
||||||
char *env = PyMem_RawMalloc(len);
|
if (!env) {
|
||||||
if (env == NULL) {
|
fprintf(stderr, "missing TESTPATH env var\n");
|
||||||
fprintf(stderr, "out of memory\n");
|
return 1;
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
strcpy(env, name);
|
wchar_t *path = Py_DecodeLocale(env, NULL);
|
||||||
strcat(env, "=");
|
if (path == NULL) {
|
||||||
strcat(env, value);
|
fprintf(stderr, "failed to decode TESTPATH\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
Py_SetPath(path);
|
||||||
|
PyMem_RawFree(path);
|
||||||
|
putenv("TESTPATH=");
|
||||||
|
|
||||||
putenv(env);
|
PyStatus status;
|
||||||
|
PyConfig config;
|
||||||
|
|
||||||
/* Don't call PyMem_RawFree(env), but leak env memory block:
|
status = PyConfig_InitPythonConfig(&config);
|
||||||
putenv() does not copy the string. */
|
if (PyStatus_Exception(status)) {
|
||||||
|
Py_ExitStatusException(status);
|
||||||
|
}
|
||||||
|
config_set_string(&config, &config.program_name, L"conf_program_name");
|
||||||
|
config_set_string(&config, &config.executable, L"conf_executable");
|
||||||
|
init_from_config_clear(&config);
|
||||||
|
|
||||||
|
dump_config();
|
||||||
|
Py_Finalize();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1485,19 +1495,6 @@ static int test_init_setpythonhome(void)
|
||||||
PyMem_RawFree(home);
|
PyMem_RawFree(home);
|
||||||
putenv("TESTHOME=");
|
putenv("TESTHOME=");
|
||||||
|
|
||||||
char *path = getenv("TESTPATH");
|
|
||||||
if (!path) {
|
|
||||||
fprintf(stderr, "missing TESTPATH env var\n");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mysetenv("PYTHONPATH", path) < 0) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
putenv("TESTPATH=");
|
|
||||||
|
|
||||||
Py_SetProgramName(PROGRAM_NAME);
|
|
||||||
|
|
||||||
Py_Initialize();
|
Py_Initialize();
|
||||||
dump_config();
|
dump_config();
|
||||||
Py_Finalize();
|
Py_Finalize();
|
||||||
|
@ -1642,6 +1639,7 @@ static struct TestCase TestCases[] = {
|
||||||
{"test_init_main", test_init_main},
|
{"test_init_main", test_init_main},
|
||||||
{"test_init_sys_add", test_init_sys_add},
|
{"test_init_sys_add", test_init_sys_add},
|
||||||
{"test_init_setpath", test_init_setpath},
|
{"test_init_setpath", test_init_setpath},
|
||||||
|
{"test_init_setpath_config", test_init_setpath_config},
|
||||||
{"test_init_setpythonhome", test_init_setpythonhome},
|
{"test_init_setpythonhome", test_init_setpythonhome},
|
||||||
{"test_run_main", test_run_main},
|
{"test_run_main", test_run_main},
|
||||||
|
|
||||||
|
|
|
@ -58,7 +58,10 @@ pathconfig_clear(_PyPathConfig *config)
|
||||||
CLEAR(config->module_search_path);
|
CLEAR(config->module_search_path);
|
||||||
CLEAR(config->program_name);
|
CLEAR(config->program_name);
|
||||||
CLEAR(config->home);
|
CLEAR(config->home);
|
||||||
|
#ifdef MS_WINDOWS
|
||||||
CLEAR(config->base_executable);
|
CLEAR(config->base_executable);
|
||||||
|
#endif
|
||||||
|
|
||||||
#undef CLEAR
|
#undef CLEAR
|
||||||
|
|
||||||
PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
|
PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
|
||||||
|
@ -83,9 +86,11 @@ pathconfig_copy(_PyPathConfig *config, const _PyPathConfig *config2)
|
||||||
COPY_ATTR(module_search_path);
|
COPY_ATTR(module_search_path);
|
||||||
COPY_ATTR(program_name);
|
COPY_ATTR(program_name);
|
||||||
COPY_ATTR(home);
|
COPY_ATTR(home);
|
||||||
|
#ifdef MS_WINDOWS
|
||||||
config->isolated = config2->isolated;
|
config->isolated = config2->isolated;
|
||||||
config->site_import = config2->site_import;
|
config->site_import = config2->site_import;
|
||||||
COPY_ATTR(base_executable);
|
COPY_ATTR(base_executable);
|
||||||
|
#endif
|
||||||
|
|
||||||
#undef COPY_ATTR
|
#undef COPY_ATTR
|
||||||
|
|
||||||
|
@ -189,12 +194,14 @@ pathconfig_set_from_config(_PyPathConfig *pathconfig, const PyConfig *config)
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
|
|
||||||
COPY_CONFIG(base_executable, base_executable);
|
|
||||||
COPY_CONFIG(program_full_path, executable);
|
COPY_CONFIG(program_full_path, executable);
|
||||||
COPY_CONFIG(prefix, prefix);
|
COPY_CONFIG(prefix, prefix);
|
||||||
COPY_CONFIG(exec_prefix, exec_prefix);
|
COPY_CONFIG(exec_prefix, exec_prefix);
|
||||||
COPY_CONFIG(program_name, program_name);
|
COPY_CONFIG(program_name, program_name);
|
||||||
COPY_CONFIG(home, home);
|
COPY_CONFIG(home, home);
|
||||||
|
#ifdef MS_WINDOWS
|
||||||
|
COPY_CONFIG(base_executable, base_executable);
|
||||||
|
#endif
|
||||||
|
|
||||||
#undef COPY_CONFIG
|
#undef COPY_CONFIG
|
||||||
|
|
||||||
|
@ -330,18 +337,32 @@ config_calculate_pathconfig(PyConfig *config)
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef MS_WINDOWS
|
||||||
|
if (config->executable != NULL && config->base_executable == NULL) {
|
||||||
|
/* If executable is set explicitly in the configuration,
|
||||||
|
ignore calculated base_executable: _PyConfig_InitPathConfig()
|
||||||
|
will copy executable to base_executable */
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
COPY_ATTR(base_executable, base_executable);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
COPY_ATTR(program_full_path, executable);
|
COPY_ATTR(program_full_path, executable);
|
||||||
COPY_ATTR(prefix, prefix);
|
COPY_ATTR(prefix, prefix);
|
||||||
COPY_ATTR(exec_prefix, exec_prefix);
|
COPY_ATTR(exec_prefix, exec_prefix);
|
||||||
COPY_ATTR(base_executable, base_executable);
|
|
||||||
#undef COPY_ATTR
|
#undef COPY_ATTR
|
||||||
|
|
||||||
|
#ifdef MS_WINDOWS
|
||||||
|
/* If a ._pth file is found: isolated and site_import are overriden */
|
||||||
if (pathconfig.isolated != -1) {
|
if (pathconfig.isolated != -1) {
|
||||||
config->isolated = pathconfig.isolated;
|
config->isolated = pathconfig.isolated;
|
||||||
}
|
}
|
||||||
if (pathconfig.site_import != -1) {
|
if (pathconfig.site_import != -1) {
|
||||||
config->site_import = pathconfig.site_import;
|
config->site_import = pathconfig.site_import;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
status = _PyStatus_OK();
|
status = _PyStatus_OK();
|
||||||
goto done;
|
goto done;
|
||||||
|
@ -360,9 +381,9 @@ _PyConfig_InitPathConfig(PyConfig *config)
|
||||||
{
|
{
|
||||||
/* Do we need to calculate the path? */
|
/* Do we need to calculate the path? */
|
||||||
if (!config->module_search_paths_set
|
if (!config->module_search_paths_set
|
||||||
|| (config->executable == NULL)
|
|| config->executable == NULL
|
||||||
|| (config->prefix == NULL)
|
|| config->prefix == NULL
|
||||||
|| (config->exec_prefix == NULL))
|
|| config->exec_prefix == NULL)
|
||||||
{
|
{
|
||||||
PyStatus status = config_calculate_pathconfig(config);
|
PyStatus status = config_calculate_pathconfig(config);
|
||||||
if (_PyStatus_EXCEPTION(status)) {
|
if (_PyStatus_EXCEPTION(status)) {
|
||||||
|
@ -442,7 +463,9 @@ pathconfig_global_init(void)
|
||||||
assert(_Py_path_config.module_search_path != NULL);
|
assert(_Py_path_config.module_search_path != NULL);
|
||||||
assert(_Py_path_config.program_name != NULL);
|
assert(_Py_path_config.program_name != NULL);
|
||||||
/* home can be NULL */
|
/* home can be NULL */
|
||||||
|
#ifdef MS_WINDOWS
|
||||||
assert(_Py_path_config.base_executable != NULL);
|
assert(_Py_path_config.base_executable != NULL);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue