mirror of
https://github.com/python/cpython
synced 2024-10-14 10:48:24 +00:00
bpo-38234: Fix _PyConfig_InitPathConfig() (GH-16335)
* _PyConfig_InitPathConfig() now starts by copying the global path configuration, and then override values set in PyConfig. * _PyPathConfig_Calculate() implementations no longer override _PyPathConfig fields which are already computed. For example, if _PyPathConfig.prefix is not NULL, leave it unchanged. * If Py_SetPath() has been called, _PyConfig_InitPathConfig() doesn't call _PyPathConfig_Calculate() anymore. * _PyPathConfig_Calculate() no longer uses PyConfig, except to initialize PyCalculatePath structure. * pathconfig_calculate(): remove useless temporary "_PyPathConfig new_config" variable. * calculate_module_search_path(): remove hack to workaround memory allocation failure, call Py_FatalError() instead. * Fix get_program_full_path(): handle memory allocation failure.
This commit is contained in:
parent
88e6447451
commit
9c42f8cda5
|
@ -1,2 +1,3 @@
|
||||||
Python ignored path passed to :c:func:`Py_SetPath`, fix Python
|
Python ignored arguments passed to :c:func:`Py_SetPath`,
|
||||||
initialization to use the specified path.
|
:c:func:`Py_SetPythonHome` and :c:func:`Py_SetProgramName`: fix Python
|
||||||
|
initialization to use specified arguments.
|
||||||
|
|
|
@ -133,6 +133,9 @@ typedef struct {
|
||||||
|
|
||||||
int prefix_found; /* found platform independent libraries? */
|
int prefix_found; /* found platform independent libraries? */
|
||||||
int exec_prefix_found; /* found the platform dependent libraries? */
|
int exec_prefix_found; /* found the platform dependent libraries? */
|
||||||
|
|
||||||
|
int warnings;
|
||||||
|
const wchar_t *pythonpath_env;
|
||||||
} PyCalculatePath;
|
} PyCalculatePath;
|
||||||
|
|
||||||
static const wchar_t delimiter[2] = {DELIM, '\0'};
|
static const wchar_t delimiter[2] = {DELIM, '\0'};
|
||||||
|
@ -365,17 +368,16 @@ add_exe_suffix(wchar_t *progpath, size_t progpathlen)
|
||||||
bytes long.
|
bytes long.
|
||||||
*/
|
*/
|
||||||
static PyStatus
|
static PyStatus
|
||||||
search_for_prefix(const PyConfig *config, PyCalculatePath *calculate,
|
search_for_prefix(PyCalculatePath *calculate, _PyPathConfig *pathconfig,
|
||||||
wchar_t *prefix, size_t prefix_len,
|
wchar_t *prefix, size_t prefix_len, int *found)
|
||||||
int *found)
|
|
||||||
{
|
{
|
||||||
PyStatus status;
|
PyStatus status;
|
||||||
size_t n;
|
size_t n;
|
||||||
wchar_t *vpath;
|
wchar_t *vpath;
|
||||||
|
|
||||||
/* If PYTHONHOME is set, we believe it unconditionally */
|
/* If PYTHONHOME is set, we believe it unconditionally */
|
||||||
if (config->home) {
|
if (pathconfig->home) {
|
||||||
if (safe_wcscpy(prefix, config->home, prefix_len) < 0) {
|
if (safe_wcscpy(prefix, pathconfig->home, prefix_len) < 0) {
|
||||||
return PATHLEN_ERR();
|
return PATHLEN_ERR();
|
||||||
}
|
}
|
||||||
wchar_t *delim = wcschr(prefix, DELIM);
|
wchar_t *delim = wcschr(prefix, DELIM);
|
||||||
|
@ -482,19 +484,19 @@ search_for_prefix(const PyConfig *config, PyCalculatePath *calculate,
|
||||||
|
|
||||||
|
|
||||||
static PyStatus
|
static PyStatus
|
||||||
calculate_prefix(const PyConfig *config,
|
calculate_prefix(PyCalculatePath *calculate, _PyPathConfig *pathconfig,
|
||||||
PyCalculatePath *calculate, wchar_t *prefix, size_t prefix_len)
|
wchar_t *prefix, size_t prefix_len)
|
||||||
{
|
{
|
||||||
PyStatus status;
|
PyStatus status;
|
||||||
|
|
||||||
status = search_for_prefix(config, calculate, prefix, prefix_len,
|
status = search_for_prefix(calculate, pathconfig, prefix, prefix_len,
|
||||||
&calculate->prefix_found);
|
&calculate->prefix_found);
|
||||||
if (_PyStatus_EXCEPTION(status)) {
|
if (_PyStatus_EXCEPTION(status)) {
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!calculate->prefix_found) {
|
if (!calculate->prefix_found) {
|
||||||
if (config->pathconfig_warnings) {
|
if (calculate->warnings) {
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"Could not find platform independent libraries <prefix>\n");
|
"Could not find platform independent libraries <prefix>\n");
|
||||||
}
|
}
|
||||||
|
@ -544,8 +546,7 @@ calculate_reduce_prefix(PyCalculatePath *calculate,
|
||||||
MAXPATHLEN bytes long.
|
MAXPATHLEN bytes long.
|
||||||
*/
|
*/
|
||||||
static PyStatus
|
static PyStatus
|
||||||
search_for_exec_prefix(const PyConfig *config,
|
search_for_exec_prefix(PyCalculatePath *calculate, _PyPathConfig *pathconfig,
|
||||||
PyCalculatePath *calculate,
|
|
||||||
wchar_t *exec_prefix, size_t exec_prefix_len,
|
wchar_t *exec_prefix, size_t exec_prefix_len,
|
||||||
int *found)
|
int *found)
|
||||||
{
|
{
|
||||||
|
@ -553,15 +554,15 @@ search_for_exec_prefix(const PyConfig *config,
|
||||||
size_t n;
|
size_t n;
|
||||||
|
|
||||||
/* If PYTHONHOME is set, we believe it unconditionally */
|
/* If PYTHONHOME is set, we believe it unconditionally */
|
||||||
if (config->home) {
|
if (pathconfig->home) {
|
||||||
wchar_t *delim = wcschr(config->home, DELIM);
|
wchar_t *delim = wcschr(pathconfig->home, DELIM);
|
||||||
if (delim) {
|
if (delim) {
|
||||||
if (safe_wcscpy(exec_prefix, delim+1, exec_prefix_len) < 0) {
|
if (safe_wcscpy(exec_prefix, delim+1, exec_prefix_len) < 0) {
|
||||||
return PATHLEN_ERR();
|
return PATHLEN_ERR();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (safe_wcscpy(exec_prefix, config->home, exec_prefix_len) < 0) {
|
if (safe_wcscpy(exec_prefix, pathconfig->home, exec_prefix_len) < 0) {
|
||||||
return PATHLEN_ERR();
|
return PATHLEN_ERR();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -668,21 +669,20 @@ search_for_exec_prefix(const PyConfig *config,
|
||||||
|
|
||||||
|
|
||||||
static PyStatus
|
static PyStatus
|
||||||
calculate_exec_prefix(const PyConfig *config,
|
calculate_exec_prefix(PyCalculatePath *calculate, _PyPathConfig *pathconfig,
|
||||||
PyCalculatePath *calculate,
|
|
||||||
wchar_t *exec_prefix, size_t exec_prefix_len)
|
wchar_t *exec_prefix, size_t exec_prefix_len)
|
||||||
{
|
{
|
||||||
PyStatus status;
|
PyStatus status;
|
||||||
|
|
||||||
status = search_for_exec_prefix(config, calculate,
|
status = search_for_exec_prefix(calculate, pathconfig,
|
||||||
exec_prefix, exec_prefix_len,
|
exec_prefix, exec_prefix_len,
|
||||||
&calculate->exec_prefix_found);
|
&calculate->exec_prefix_found);
|
||||||
if (_PyStatus_EXCEPTION(status)) {
|
if (_PyStatus_EXCEPTION(status)) {
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!calculate->exec_prefix_found) {
|
if (!calculate->exec_prefix_found) {
|
||||||
if (config->pathconfig_warnings) {
|
if (calculate->warnings) {
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"Could not find platform dependent libraries <exec_prefix>\n");
|
"Could not find platform dependent libraries <exec_prefix>\n");
|
||||||
}
|
}
|
||||||
|
@ -721,8 +721,7 @@ calculate_reduce_exec_prefix(PyCalculatePath *calculate,
|
||||||
|
|
||||||
|
|
||||||
static PyStatus
|
static PyStatus
|
||||||
calculate_program_full_path(const PyConfig *config,
|
calculate_program_full_path(PyCalculatePath *calculate, _PyPathConfig *pathconfig)
|
||||||
PyCalculatePath *calculate, _PyPathConfig *pathconfig)
|
|
||||||
{
|
{
|
||||||
PyStatus status;
|
PyStatus status;
|
||||||
wchar_t program_full_path[MAXPATHLEN + 1];
|
wchar_t program_full_path[MAXPATHLEN + 1];
|
||||||
|
@ -743,8 +742,8 @@ calculate_program_full_path(const PyConfig *config,
|
||||||
* other way to find a directory to start the search from. If
|
* other way to find a directory to start the search from. If
|
||||||
* $PATH isn't exported, you lose.
|
* $PATH isn't exported, you lose.
|
||||||
*/
|
*/
|
||||||
if (wcschr(config->program_name, SEP)) {
|
if (wcschr(pathconfig->program_name, SEP)) {
|
||||||
if (safe_wcscpy(program_full_path, config->program_name,
|
if (safe_wcscpy(program_full_path, pathconfig->program_name,
|
||||||
program_full_path_len) < 0) {
|
program_full_path_len) < 0) {
|
||||||
return PATHLEN_ERR();
|
return PATHLEN_ERR();
|
||||||
}
|
}
|
||||||
|
@ -795,8 +794,8 @@ calculate_program_full_path(const PyConfig *config,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
status = joinpath(program_full_path, config->program_name,
|
status = joinpath(program_full_path, pathconfig->program_name,
|
||||||
program_full_path_len);
|
program_full_path_len);
|
||||||
if (_PyStatus_EXCEPTION(status)) {
|
if (_PyStatus_EXCEPTION(status)) {
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
@ -1030,15 +1029,14 @@ calculate_zip_path(PyCalculatePath *calculate, const wchar_t *prefix)
|
||||||
|
|
||||||
|
|
||||||
static PyStatus
|
static PyStatus
|
||||||
calculate_module_search_path(const PyConfig *config,
|
calculate_module_search_path(PyCalculatePath *calculate,
|
||||||
PyCalculatePath *calculate,
|
_PyPathConfig *pathconfig,
|
||||||
const wchar_t *prefix, const wchar_t *exec_prefix,
|
const wchar_t *prefix, const wchar_t *exec_prefix)
|
||||||
_PyPathConfig *pathconfig)
|
|
||||||
{
|
{
|
||||||
/* Calculate size of return buffer */
|
/* Calculate size of return buffer */
|
||||||
size_t bufsz = 0;
|
size_t bufsz = 0;
|
||||||
if (config->pythonpath_env != NULL) {
|
if (calculate->pythonpath_env != NULL) {
|
||||||
bufsz += wcslen(config->pythonpath_env) + 1;
|
bufsz += wcslen(calculate->pythonpath_env) + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
wchar_t *defpath = calculate->pythonpath;
|
wchar_t *defpath = calculate->pythonpath;
|
||||||
|
@ -1072,8 +1070,8 @@ calculate_module_search_path(const PyConfig *config,
|
||||||
buf[0] = '\0';
|
buf[0] = '\0';
|
||||||
|
|
||||||
/* Run-time value of $PYTHONPATH goes first */
|
/* Run-time value of $PYTHONPATH goes first */
|
||||||
if (config->pythonpath_env) {
|
if (calculate->pythonpath_env) {
|
||||||
wcscpy(buf, config->pythonpath_env);
|
wcscpy(buf, calculate->pythonpath_env);
|
||||||
wcscat(buf, delimiter);
|
wcscat(buf, delimiter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1149,6 +1147,10 @@ calculate_init(PyCalculatePath *calculate,
|
||||||
if (!calculate->lib_python) {
|
if (!calculate->lib_python) {
|
||||||
return DECODE_LOCALE_ERR("EXEC_PREFIX define", len);
|
return DECODE_LOCALE_ERR("EXEC_PREFIX define", len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
calculate->warnings = config->pathconfig_warnings;
|
||||||
|
calculate->pythonpath_env = config->pythonpath_env;
|
||||||
|
|
||||||
return _PyStatus_OK();
|
return _PyStatus_OK();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1165,14 +1167,15 @@ calculate_free(PyCalculatePath *calculate)
|
||||||
|
|
||||||
|
|
||||||
static PyStatus
|
static PyStatus
|
||||||
calculate_path_impl(const PyConfig *config,
|
calculate_path(PyCalculatePath *calculate, _PyPathConfig *pathconfig)
|
||||||
PyCalculatePath *calculate, _PyPathConfig *pathconfig)
|
|
||||||
{
|
{
|
||||||
PyStatus status;
|
PyStatus status;
|
||||||
|
|
||||||
status = calculate_program_full_path(config, calculate, pathconfig);
|
if (pathconfig->program_full_path == NULL) {
|
||||||
if (_PyStatus_EXCEPTION(status)) {
|
status = calculate_program_full_path(calculate, pathconfig);
|
||||||
return status;
|
if (_PyStatus_EXCEPTION(status)) {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
status = calculate_argv0_path(calculate, pathconfig->program_full_path);
|
status = calculate_argv0_path(calculate, pathconfig->program_full_path);
|
||||||
|
@ -1187,8 +1190,8 @@ calculate_path_impl(const PyConfig *config,
|
||||||
|
|
||||||
wchar_t prefix[MAXPATHLEN+1];
|
wchar_t prefix[MAXPATHLEN+1];
|
||||||
memset(prefix, 0, sizeof(prefix));
|
memset(prefix, 0, sizeof(prefix));
|
||||||
status = calculate_prefix(config, calculate,
|
status = calculate_prefix(calculate, pathconfig,
|
||||||
prefix, Py_ARRAY_LENGTH(prefix));
|
prefix, Py_ARRAY_LENGTH(prefix));
|
||||||
if (_PyStatus_EXCEPTION(status)) {
|
if (_PyStatus_EXCEPTION(status)) {
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
@ -1200,52 +1203,65 @@ calculate_path_impl(const PyConfig *config,
|
||||||
|
|
||||||
wchar_t exec_prefix[MAXPATHLEN+1];
|
wchar_t exec_prefix[MAXPATHLEN+1];
|
||||||
memset(exec_prefix, 0, sizeof(exec_prefix));
|
memset(exec_prefix, 0, sizeof(exec_prefix));
|
||||||
status = calculate_exec_prefix(config, calculate,
|
status = calculate_exec_prefix(calculate, pathconfig,
|
||||||
exec_prefix, Py_ARRAY_LENGTH(exec_prefix));
|
exec_prefix, Py_ARRAY_LENGTH(exec_prefix));
|
||||||
if (_PyStatus_EXCEPTION(status)) {
|
if (_PyStatus_EXCEPTION(status)) {
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((!calculate->prefix_found || !calculate->exec_prefix_found) &&
|
if ((!calculate->prefix_found || !calculate->exec_prefix_found) &&
|
||||||
config->pathconfig_warnings)
|
calculate->warnings)
|
||||||
{
|
{
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"Consider setting $PYTHONHOME to <prefix>[:<exec_prefix>]\n");
|
"Consider setting $PYTHONHOME to <prefix>[:<exec_prefix>]\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pathconfig->module_search_path == NULL) {
|
if (pathconfig->module_search_path == NULL) {
|
||||||
status = calculate_module_search_path(config, calculate,
|
status = calculate_module_search_path(calculate, pathconfig,
|
||||||
prefix, exec_prefix, pathconfig);
|
prefix, exec_prefix);
|
||||||
if (_PyStatus_EXCEPTION(status)) {
|
if (_PyStatus_EXCEPTION(status)) {
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
status = calculate_reduce_prefix(calculate, prefix, Py_ARRAY_LENGTH(prefix));
|
|
||||||
if (_PyStatus_EXCEPTION(status)) {
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
pathconfig->prefix = _PyMem_RawWcsdup(prefix);
|
|
||||||
if (pathconfig->prefix == NULL) {
|
if (pathconfig->prefix == NULL) {
|
||||||
return _PyStatus_NO_MEMORY();
|
status = calculate_reduce_prefix(calculate, prefix, Py_ARRAY_LENGTH(prefix));
|
||||||
|
if (_PyStatus_EXCEPTION(status)) {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
pathconfig->prefix = _PyMem_RawWcsdup(prefix);
|
||||||
|
if (pathconfig->prefix == NULL) {
|
||||||
|
return _PyStatus_NO_MEMORY();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
status = calculate_reduce_exec_prefix(calculate,
|
|
||||||
exec_prefix, Py_ARRAY_LENGTH(exec_prefix));
|
|
||||||
if (_PyStatus_EXCEPTION(status)) {
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
pathconfig->exec_prefix = _PyMem_RawWcsdup(exec_prefix);
|
|
||||||
if (pathconfig->exec_prefix == NULL) {
|
if (pathconfig->exec_prefix == NULL) {
|
||||||
return _PyStatus_NO_MEMORY();
|
status = calculate_reduce_exec_prefix(calculate,
|
||||||
|
exec_prefix,
|
||||||
|
Py_ARRAY_LENGTH(exec_prefix));
|
||||||
|
if (_PyStatus_EXCEPTION(status)) {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
pathconfig->exec_prefix = _PyMem_RawWcsdup(exec_prefix);
|
||||||
|
if (pathconfig->exec_prefix == NULL) {
|
||||||
|
return _PyStatus_NO_MEMORY();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return _PyStatus_OK();
|
return _PyStatus_OK();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Calculate 'pathconfig' attributes:
|
||||||
|
|
||||||
|
- program_full_path
|
||||||
|
- module_search_path
|
||||||
|
- prefix
|
||||||
|
- exec_prefix
|
||||||
|
|
||||||
|
If an attribute is already set (non NULL), it is left unchanged. */
|
||||||
PyStatus
|
PyStatus
|
||||||
_PyPathConfig_Calculate(_PyPathConfig *pathconfig, const PyConfig *config)
|
_PyPathConfig_Calculate(_PyPathConfig *pathconfig, const PyConfig *config)
|
||||||
{
|
{
|
||||||
|
@ -1258,7 +1274,7 @@ _PyPathConfig_Calculate(_PyPathConfig *pathconfig, const PyConfig *config)
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
status = calculate_path_impl(config, &calculate, pathconfig);
|
status = calculate_path(&calculate, pathconfig);
|
||||||
if (_PyStatus_EXCEPTION(status)) {
|
if (_PyStatus_EXCEPTION(status)) {
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
110
PC/getpathp.c
110
PC/getpathp.c
|
@ -130,6 +130,8 @@ typedef struct {
|
||||||
wchar_t zip_path[MAXPATHLEN+1];
|
wchar_t zip_path[MAXPATHLEN+1];
|
||||||
|
|
||||||
wchar_t *dll_path;
|
wchar_t *dll_path;
|
||||||
|
|
||||||
|
const wchar_t *pythonpath_env;
|
||||||
} PyCalculatePath;
|
} PyCalculatePath;
|
||||||
|
|
||||||
|
|
||||||
|
@ -322,7 +324,7 @@ gotlandmark(wchar_t *prefix, const wchar_t *landmark)
|
||||||
|
|
||||||
|
|
||||||
/* assumes argv0_path is MAXPATHLEN+1 bytes long, already \0 term'd.
|
/* assumes argv0_path is MAXPATHLEN+1 bytes long, already \0 term'd.
|
||||||
assumption provided by only caller, calculate_path_impl() */
|
assumption provided by only caller, calculate_path() */
|
||||||
static int
|
static int
|
||||||
search_for_prefix(wchar_t *prefix, const wchar_t *argv0_path, const wchar_t *landmark)
|
search_for_prefix(wchar_t *prefix, const wchar_t *argv0_path, const wchar_t *landmark)
|
||||||
{
|
{
|
||||||
|
@ -534,6 +536,7 @@ _Py_GetDLLPath(void)
|
||||||
static PyStatus
|
static PyStatus
|
||||||
get_program_full_path(_PyPathConfig *pathconfig)
|
get_program_full_path(_PyPathConfig *pathconfig)
|
||||||
{
|
{
|
||||||
|
PyStatus status;
|
||||||
const wchar_t *pyvenv_launcher;
|
const wchar_t *pyvenv_launcher;
|
||||||
wchar_t program_full_path[MAXPATHLEN+1];
|
wchar_t program_full_path[MAXPATHLEN+1];
|
||||||
memset(program_full_path, 0, sizeof(program_full_path));
|
memset(program_full_path, 0, sizeof(program_full_path));
|
||||||
|
@ -548,12 +551,18 @@ get_program_full_path(_PyPathConfig *pathconfig)
|
||||||
pyvenv_launcher = _wgetenv(L"__PYVENV_LAUNCHER__");
|
pyvenv_launcher = _wgetenv(L"__PYVENV_LAUNCHER__");
|
||||||
if (pyvenv_launcher && pyvenv_launcher[0]) {
|
if (pyvenv_launcher && pyvenv_launcher[0]) {
|
||||||
/* If overridden, preserve the original full path */
|
/* If overridden, preserve the original full path */
|
||||||
pathconfig->base_executable = PyMem_RawMalloc(
|
if (pathconfig->base_executable == NULL) {
|
||||||
sizeof(wchar_t) * (MAXPATHLEN + 1));
|
pathconfig->base_executable = PyMem_RawMalloc(
|
||||||
PyStatus status = canonicalize(pathconfig->base_executable,
|
sizeof(wchar_t) * (MAXPATHLEN + 1));
|
||||||
program_full_path);
|
if (pathconfig->base_executable == NULL) {
|
||||||
if (_PyStatus_EXCEPTION(status)) {
|
return _PyStatus_NO_MEMORY();
|
||||||
return status;
|
}
|
||||||
|
|
||||||
|
status = canonicalize(pathconfig->base_executable,
|
||||||
|
program_full_path);
|
||||||
|
if (_PyStatus_EXCEPTION(status)) {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
wcscpy_s(program_full_path, MAXPATHLEN+1, pyvenv_launcher);
|
wcscpy_s(program_full_path, MAXPATHLEN+1, pyvenv_launcher);
|
||||||
|
@ -562,11 +571,20 @@ get_program_full_path(_PyPathConfig *pathconfig)
|
||||||
_wputenv_s(L"__PYVENV_LAUNCHER__", L"");
|
_wputenv_s(L"__PYVENV_LAUNCHER__", L"");
|
||||||
}
|
}
|
||||||
|
|
||||||
pathconfig->program_full_path = PyMem_RawMalloc(
|
if (pathconfig->program_full_path == NULL) {
|
||||||
sizeof(wchar_t) * (MAXPATHLEN + 1));
|
pathconfig->program_full_path = PyMem_RawMalloc(
|
||||||
|
sizeof(wchar_t) * (MAXPATHLEN + 1));
|
||||||
|
if (pathconfig->program_full_path == NULL) {
|
||||||
|
return _PyStatus_NO_MEMORY();
|
||||||
|
}
|
||||||
|
|
||||||
return canonicalize(pathconfig->program_full_path,
|
status = canonicalize(pathconfig->program_full_path,
|
||||||
program_full_path);
|
program_full_path);
|
||||||
|
if (_PyStatus_EXCEPTION(status)) {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return _PyStatus_OK();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -657,7 +675,13 @@ read_pth_file(_PyPathConfig *pathconfig, wchar_t *prefix, const wchar_t *path)
|
||||||
}
|
}
|
||||||
|
|
||||||
fclose(sp_file);
|
fclose(sp_file);
|
||||||
pathconfig->module_search_path = buf;
|
if (pathconfig->module_search_path == NULL) {
|
||||||
|
pathconfig->module_search_path = _PyMem_RawWcsdup(buf);
|
||||||
|
if (pathconfig->module_search_path == NULL) {
|
||||||
|
Py_FatalError("out of memory");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
PyMem_RawFree(buf);
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
|
@ -668,8 +692,7 @@ read_pth_file(_PyPathConfig *pathconfig, wchar_t *prefix, const wchar_t *path)
|
||||||
|
|
||||||
|
|
||||||
static PyStatus
|
static PyStatus
|
||||||
calculate_init(PyCalculatePath *calculate,
|
calculate_init(PyCalculatePath *calculate, const PyConfig *config)
|
||||||
const PyConfig *config)
|
|
||||||
{
|
{
|
||||||
calculate->home = config->home;
|
calculate->home = config->home;
|
||||||
calculate->path_env = _wgetenv(L"PATH");
|
calculate->path_env = _wgetenv(L"PATH");
|
||||||
|
@ -679,6 +702,8 @@ calculate_init(PyCalculatePath *calculate,
|
||||||
return _PyStatus_NO_MEMORY();
|
return _PyStatus_NO_MEMORY();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
calculate->pythonpath_env = config->pythonpath_env;
|
||||||
|
|
||||||
return _PyStatus_OK();
|
return _PyStatus_OK();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -785,8 +810,8 @@ calculate_home_prefix(PyCalculatePath *calculate, wchar_t *prefix)
|
||||||
|
|
||||||
|
|
||||||
static PyStatus
|
static PyStatus
|
||||||
calculate_module_search_path(const PyConfig *config,
|
calculate_module_search_path(PyCalculatePath *calculate,
|
||||||
PyCalculatePath *calculate, _PyPathConfig *pathconfig,
|
_PyPathConfig *pathconfig,
|
||||||
wchar_t *prefix)
|
wchar_t *prefix)
|
||||||
{
|
{
|
||||||
int skiphome = calculate->home==NULL ? 0 : 1;
|
int skiphome = calculate->home==NULL ? 0 : 1;
|
||||||
|
@ -796,7 +821,7 @@ calculate_module_search_path(const PyConfig *config,
|
||||||
#endif
|
#endif
|
||||||
/* We only use the default relative PYTHONPATH if we haven't
|
/* We only use the default relative PYTHONPATH if we haven't
|
||||||
anything better to use! */
|
anything better to use! */
|
||||||
int skipdefault = (config->pythonpath_env != NULL ||
|
int skipdefault = (calculate->pythonpath_env != NULL ||
|
||||||
calculate->home != NULL ||
|
calculate->home != NULL ||
|
||||||
calculate->machine_path != NULL ||
|
calculate->machine_path != NULL ||
|
||||||
calculate->user_path != NULL);
|
calculate->user_path != NULL);
|
||||||
|
@ -835,30 +860,20 @@ calculate_module_search_path(const PyConfig *config,
|
||||||
bufsz += wcslen(calculate->machine_path) + 1;
|
bufsz += wcslen(calculate->machine_path) + 1;
|
||||||
}
|
}
|
||||||
bufsz += wcslen(calculate->zip_path) + 1;
|
bufsz += wcslen(calculate->zip_path) + 1;
|
||||||
if (config->pythonpath_env != NULL) {
|
if (calculate->pythonpath_env != NULL) {
|
||||||
bufsz += wcslen(config->pythonpath_env) + 1;
|
bufsz += wcslen(calculate->pythonpath_env) + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
wchar_t *buf, *start_buf;
|
wchar_t *buf, *start_buf;
|
||||||
buf = PyMem_RawMalloc(bufsz * sizeof(wchar_t));
|
buf = PyMem_RawMalloc(bufsz * sizeof(wchar_t));
|
||||||
if (buf == NULL) {
|
if (buf == NULL) {
|
||||||
/* We can't exit, so print a warning and limp along */
|
Py_FatalError("Can't malloc dynamic PYTHONPATH");
|
||||||
fprintf(stderr, "Can't malloc dynamic PYTHONPATH.\n");
|
|
||||||
if (config->pythonpath_env) {
|
|
||||||
fprintf(stderr, "Using environment $PYTHONPATH.\n");
|
|
||||||
pathconfig->module_search_path = config->pythonpath_env;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
fprintf(stderr, "Using default static path.\n");
|
|
||||||
pathconfig->module_search_path = PYTHONPATH;
|
|
||||||
}
|
|
||||||
return _PyStatus_OK();
|
|
||||||
}
|
}
|
||||||
start_buf = buf;
|
start_buf = buf;
|
||||||
|
|
||||||
if (config->pythonpath_env) {
|
if (calculate->pythonpath_env) {
|
||||||
if (wcscpy_s(buf, bufsz - (buf - start_buf),
|
if (wcscpy_s(buf, bufsz - (buf - start_buf),
|
||||||
config->pythonpath_env)) {
|
calculate->pythonpath_env)) {
|
||||||
return INIT_ERR_BUFFER_OVERFLOW();
|
return INIT_ERR_BUFFER_OVERFLOW();
|
||||||
}
|
}
|
||||||
buf = wcschr(buf, L'\0');
|
buf = wcschr(buf, L'\0');
|
||||||
|
@ -971,8 +986,7 @@ calculate_module_search_path(const PyConfig *config,
|
||||||
|
|
||||||
|
|
||||||
static PyStatus
|
static PyStatus
|
||||||
calculate_path_impl(const PyConfig *config,
|
calculate_path(PyCalculatePath *calculate, _PyPathConfig *pathconfig)
|
||||||
PyCalculatePath *calculate, _PyPathConfig *pathconfig)
|
|
||||||
{
|
{
|
||||||
PyStatus status;
|
PyStatus status;
|
||||||
|
|
||||||
|
@ -1003,21 +1017,24 @@ calculate_path_impl(const PyConfig *config,
|
||||||
calculate_home_prefix(calculate, prefix);
|
calculate_home_prefix(calculate, prefix);
|
||||||
|
|
||||||
if (pathconfig->module_search_path == NULL) {
|
if (pathconfig->module_search_path == NULL) {
|
||||||
status = calculate_module_search_path(config, calculate,
|
status = calculate_module_search_path(calculate, pathconfig, prefix);
|
||||||
pathconfig, prefix);
|
|
||||||
if (_PyStatus_EXCEPTION(status)) {
|
if (_PyStatus_EXCEPTION(status)) {
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
done:
|
done:
|
||||||
pathconfig->prefix = _PyMem_RawWcsdup(prefix);
|
|
||||||
if (pathconfig->prefix == NULL) {
|
if (pathconfig->prefix == NULL) {
|
||||||
return _PyStatus_NO_MEMORY();
|
pathconfig->prefix = _PyMem_RawWcsdup(prefix);
|
||||||
|
if (pathconfig->prefix == NULL) {
|
||||||
|
return _PyStatus_NO_MEMORY();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
pathconfig->exec_prefix = _PyMem_RawWcsdup(prefix);
|
|
||||||
if (pathconfig->exec_prefix == NULL) {
|
if (pathconfig->exec_prefix == NULL) {
|
||||||
return _PyStatus_NO_MEMORY();
|
pathconfig->exec_prefix = _PyMem_RawWcsdup(prefix);
|
||||||
|
if (pathconfig->exec_prefix == NULL) {
|
||||||
|
return _PyStatus_NO_MEMORY();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return _PyStatus_OK();
|
return _PyStatus_OK();
|
||||||
|
@ -1033,6 +1050,17 @@ calculate_free(PyCalculatePath *calculate)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Calculate 'pathconfig' attributes:
|
||||||
|
|
||||||
|
- base_executable
|
||||||
|
- program_full_path
|
||||||
|
- module_search_path
|
||||||
|
- prefix
|
||||||
|
- exec_prefix
|
||||||
|
- isolated
|
||||||
|
- site_import
|
||||||
|
|
||||||
|
If an attribute is already set (non NULL), it is left unchanged. */
|
||||||
PyStatus
|
PyStatus
|
||||||
_PyPathConfig_Calculate(_PyPathConfig *pathconfig, const PyConfig *config)
|
_PyPathConfig_Calculate(_PyPathConfig *pathconfig, const PyConfig *config)
|
||||||
{
|
{
|
||||||
|
@ -1045,7 +1073,7 @@ _PyPathConfig_Calculate(_PyPathConfig *pathconfig, const PyConfig *config)
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
status = calculate_path_impl(config, &calculate, pathconfig);
|
status = calculate_path(&calculate, pathconfig);
|
||||||
|
|
||||||
done:
|
done:
|
||||||
calculate_free(&calculate);
|
calculate_free(&calculate);
|
||||||
|
|
|
@ -51,12 +51,12 @@ pathconfig_clear(_PyPathConfig *config)
|
||||||
ATTR = NULL; \
|
ATTR = NULL; \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
CLEAR(config->prefix);
|
|
||||||
CLEAR(config->program_full_path);
|
CLEAR(config->program_full_path);
|
||||||
|
CLEAR(config->prefix);
|
||||||
CLEAR(config->exec_prefix);
|
CLEAR(config->exec_prefix);
|
||||||
CLEAR(config->module_search_path);
|
CLEAR(config->module_search_path);
|
||||||
CLEAR(config->home);
|
|
||||||
CLEAR(config->program_name);
|
CLEAR(config->program_name);
|
||||||
|
CLEAR(config->home);
|
||||||
CLEAR(config->base_executable);
|
CLEAR(config->base_executable);
|
||||||
#undef CLEAR
|
#undef CLEAR
|
||||||
|
|
||||||
|
@ -64,60 +64,31 @@ pathconfig_clear(_PyPathConfig *config)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Calculate the path configuration: initialize pathconfig from config */
|
|
||||||
static PyStatus
|
static PyStatus
|
||||||
pathconfig_calculate(_PyPathConfig *pathconfig, const PyConfig *config)
|
pathconfig_copy(_PyPathConfig *config, const _PyPathConfig *config2)
|
||||||
{
|
{
|
||||||
PyStatus status;
|
pathconfig_clear(config);
|
||||||
_PyPathConfig new_config = _PyPathConfig_INIT;
|
|
||||||
|
|
||||||
PyMemAllocatorEx old_alloc;
|
#define COPY_ATTR(ATTR) \
|
||||||
_PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
|
do { \
|
||||||
|
if (copy_wstr(&config->ATTR, config2->ATTR) < 0) { \
|
||||||
|
return _PyStatus_NO_MEMORY(); \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
if (copy_wstr(&new_config.module_search_path,
|
COPY_ATTR(program_full_path);
|
||||||
_Py_path_config.module_search_path) < 0)
|
COPY_ATTR(prefix);
|
||||||
{
|
COPY_ATTR(exec_prefix);
|
||||||
status = _PyStatus_NO_MEMORY();
|
COPY_ATTR(module_search_path);
|
||||||
goto error;
|
COPY_ATTR(program_name);
|
||||||
}
|
COPY_ATTR(home);
|
||||||
|
config->isolated = config2->isolated;
|
||||||
|
config->site_import = config2->site_import;
|
||||||
|
COPY_ATTR(base_executable);
|
||||||
|
|
||||||
/* Calculate program_full_path, prefix, exec_prefix,
|
#undef COPY_ATTR
|
||||||
dll_path (Windows), and module_search_path */
|
|
||||||
status = _PyPathConfig_Calculate(&new_config, config);
|
|
||||||
if (_PyStatus_EXCEPTION(status)) {
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Copy home and program_name from config */
|
return _PyStatus_OK();
|
||||||
if (copy_wstr(&new_config.home, config->home) < 0) {
|
|
||||||
status = _PyStatus_NO_MEMORY();
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
if (copy_wstr(&new_config.program_name, config->program_name) < 0) {
|
|
||||||
status = _PyStatus_NO_MEMORY();
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
if (config->base_executable) {
|
|
||||||
PyMem_RawFree(new_config.base_executable);
|
|
||||||
if (copy_wstr(&new_config.base_executable,
|
|
||||||
config->base_executable) < 0) {
|
|
||||||
status = _PyStatus_NO_MEMORY();
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pathconfig_clear(pathconfig);
|
|
||||||
*pathconfig = new_config;
|
|
||||||
|
|
||||||
status = _PyStatus_OK();
|
|
||||||
goto done;
|
|
||||||
|
|
||||||
error:
|
|
||||||
pathconfig_clear(&new_config);
|
|
||||||
|
|
||||||
done:
|
|
||||||
PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
|
|
||||||
return status;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -168,7 +139,7 @@ _PyWideStringList_Join(const PyWideStringList *list, wchar_t sep)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Set the global path configuration from config. */
|
/* Initialize _Py_dll_path on Windows. Do nothing on other platforms. */
|
||||||
PyStatus
|
PyStatus
|
||||||
_PyPathConfig_Init(void)
|
_PyPathConfig_Init(void)
|
||||||
{
|
{
|
||||||
|
@ -194,47 +165,39 @@ _PyPathConfig_Init(void)
|
||||||
|
|
||||||
|
|
||||||
static PyStatus
|
static PyStatus
|
||||||
pathconfig_global_init_from_config(const PyConfig *config)
|
pathconfig_set_from_config(_PyPathConfig *pathconfig, const PyConfig *config)
|
||||||
{
|
{
|
||||||
PyStatus status;
|
PyStatus status;
|
||||||
PyMemAllocatorEx old_alloc;
|
PyMemAllocatorEx old_alloc;
|
||||||
_PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
|
_PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
|
||||||
|
|
||||||
_PyPathConfig pathconfig = _PyPathConfig_INIT;
|
if (config->module_search_paths_set) {
|
||||||
|
pathconfig->module_search_path = _PyWideStringList_Join(&config->module_search_paths, DELIM);
|
||||||
pathconfig.module_search_path = _PyWideStringList_Join(&config->module_search_paths, DELIM);
|
if (pathconfig->module_search_path == NULL) {
|
||||||
if (pathconfig.module_search_path == NULL) {
|
goto no_memory;
|
||||||
goto no_memory;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (copy_wstr(&pathconfig.program_full_path, config->executable) < 0) {
|
#define COPY_CONFIG(PATH_ATTR, CONFIG_ATTR) \
|
||||||
goto no_memory;
|
if (config->CONFIG_ATTR) { \
|
||||||
}
|
if (copy_wstr(&pathconfig->PATH_ATTR, config->CONFIG_ATTR) < 0) { \
|
||||||
if (copy_wstr(&pathconfig.prefix, config->prefix) < 0) {
|
goto no_memory; \
|
||||||
goto no_memory;
|
} \
|
||||||
}
|
}
|
||||||
if (copy_wstr(&pathconfig.exec_prefix, config->exec_prefix) < 0) {
|
|
||||||
goto no_memory;
|
|
||||||
}
|
|
||||||
if (copy_wstr(&pathconfig.program_name, config->program_name) < 0) {
|
|
||||||
goto no_memory;
|
|
||||||
}
|
|
||||||
if (copy_wstr(&pathconfig.home, config->home) < 0) {
|
|
||||||
goto no_memory;
|
|
||||||
}
|
|
||||||
if (copy_wstr(&pathconfig.base_executable, config->base_executable) < 0) {
|
|
||||||
goto no_memory;
|
|
||||||
}
|
|
||||||
|
|
||||||
pathconfig_clear(&_Py_path_config);
|
COPY_CONFIG(base_executable, base_executable);
|
||||||
/* Steal new_config strings; don't clear new_config */
|
COPY_CONFIG(program_full_path, executable);
|
||||||
_Py_path_config = pathconfig;
|
COPY_CONFIG(prefix, prefix);
|
||||||
|
COPY_CONFIG(exec_prefix, exec_prefix);
|
||||||
|
COPY_CONFIG(program_name, program_name);
|
||||||
|
COPY_CONFIG(home, home);
|
||||||
|
|
||||||
|
#undef COPY_CONFIG
|
||||||
|
|
||||||
status = _PyStatus_OK();
|
status = _PyStatus_OK();
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
no_memory:
|
no_memory:
|
||||||
pathconfig_clear(&pathconfig);
|
|
||||||
status = _PyStatus_NO_MEMORY();
|
status = _PyStatus_NO_MEMORY();
|
||||||
|
|
||||||
done:
|
done:
|
||||||
|
@ -283,6 +246,61 @@ config_init_module_search_paths(PyConfig *config, _PyPathConfig *pathconfig)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Calculate the path configuration:
|
||||||
|
|
||||||
|
- exec_prefix
|
||||||
|
- module_search_path
|
||||||
|
- prefix
|
||||||
|
- program_full_path
|
||||||
|
|
||||||
|
On Windows, more fields are calculated:
|
||||||
|
|
||||||
|
- base_executable
|
||||||
|
- isolated
|
||||||
|
- site_import
|
||||||
|
|
||||||
|
On other platforms, isolated and site_import are left unchanged, and
|
||||||
|
_PyConfig_InitPathConfig() copies executable to base_executable (if it's not
|
||||||
|
set).
|
||||||
|
|
||||||
|
Priority, highest to lowest:
|
||||||
|
|
||||||
|
- PyConfig
|
||||||
|
- _Py_path_config: set by Py_SetPath(), Py_SetPythonHome()
|
||||||
|
and Py_SetProgramName()
|
||||||
|
- _PyPathConfig_Calculate()
|
||||||
|
*/
|
||||||
|
static PyStatus
|
||||||
|
pathconfig_calculate(_PyPathConfig *pathconfig, const PyConfig *config)
|
||||||
|
{
|
||||||
|
PyStatus status;
|
||||||
|
|
||||||
|
PyMemAllocatorEx old_alloc;
|
||||||
|
_PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
|
||||||
|
|
||||||
|
status = pathconfig_copy(pathconfig, &_Py_path_config);
|
||||||
|
if (_PyStatus_EXCEPTION(status)) {
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
status = pathconfig_set_from_config(pathconfig, config);
|
||||||
|
if (_PyStatus_EXCEPTION(status)) {
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_Py_path_config.module_search_path == NULL) {
|
||||||
|
status = _PyPathConfig_Calculate(pathconfig, config);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* Py_SetPath() has been called: avoid _PyPathConfig_Calculate() */
|
||||||
|
}
|
||||||
|
|
||||||
|
done:
|
||||||
|
PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static PyStatus
|
static PyStatus
|
||||||
config_calculate_pathconfig(PyConfig *config)
|
config_calculate_pathconfig(PyConfig *config)
|
||||||
{
|
{
|
||||||
|
@ -291,42 +309,28 @@ config_calculate_pathconfig(PyConfig *config)
|
||||||
|
|
||||||
status = pathconfig_calculate(&pathconfig, config);
|
status = pathconfig_calculate(&pathconfig, config);
|
||||||
if (_PyStatus_EXCEPTION(status)) {
|
if (_PyStatus_EXCEPTION(status)) {
|
||||||
goto error;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!config->module_search_paths_set) {
|
if (!config->module_search_paths_set) {
|
||||||
status = config_init_module_search_paths(config, &pathconfig);
|
status = config_init_module_search_paths(config, &pathconfig);
|
||||||
if (_PyStatus_EXCEPTION(status)) {
|
if (_PyStatus_EXCEPTION(status)) {
|
||||||
goto error;
|
goto done;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (config->executable == NULL) {
|
#define COPY_ATTR(PATH_ATTR, CONFIG_ATTR) \
|
||||||
if (copy_wstr(&config->executable,
|
if (config->CONFIG_ATTR == NULL) { \
|
||||||
pathconfig.program_full_path) < 0) {
|
if (copy_wstr(&config->CONFIG_ATTR, pathconfig.PATH_ATTR) < 0) { \
|
||||||
goto no_memory;
|
goto no_memory; \
|
||||||
|
} \
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (config->prefix == NULL) {
|
COPY_ATTR(program_full_path, executable);
|
||||||
if (copy_wstr(&config->prefix, pathconfig.prefix) < 0) {
|
COPY_ATTR(prefix, prefix);
|
||||||
goto no_memory;
|
COPY_ATTR(exec_prefix, exec_prefix);
|
||||||
}
|
COPY_ATTR(base_executable, base_executable);
|
||||||
}
|
#undef COPY_ATTR
|
||||||
|
|
||||||
if (config->exec_prefix == NULL) {
|
|
||||||
if (copy_wstr(&config->exec_prefix,
|
|
||||||
pathconfig.exec_prefix) < 0) {
|
|
||||||
goto no_memory;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (config->base_executable == NULL) {
|
|
||||||
if (copy_wstr(&config->base_executable,
|
|
||||||
pathconfig.base_executable) < 0) {
|
|
||||||
goto no_memory;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pathconfig.isolated != -1) {
|
if (pathconfig.isolated != -1) {
|
||||||
config->isolated = pathconfig.isolated;
|
config->isolated = pathconfig.isolated;
|
||||||
|
@ -335,13 +339,13 @@ config_calculate_pathconfig(PyConfig *config)
|
||||||
config->site_import = pathconfig.site_import;
|
config->site_import = pathconfig.site_import;
|
||||||
}
|
}
|
||||||
|
|
||||||
pathconfig_clear(&pathconfig);
|
status = _PyStatus_OK();
|
||||||
return _PyStatus_OK();
|
goto done;
|
||||||
|
|
||||||
no_memory:
|
no_memory:
|
||||||
status = _PyStatus_NO_MEMORY();
|
status = _PyStatus_NO_MEMORY();
|
||||||
|
|
||||||
error:
|
done:
|
||||||
pathconfig_clear(&pathconfig);
|
pathconfig_clear(&pathconfig);
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
@ -386,39 +390,55 @@ _PyConfig_InitPathConfig(PyConfig *config)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static PyStatus
|
||||||
|
pathconfig_global_read(_PyPathConfig *pathconfig)
|
||||||
|
{
|
||||||
|
PyStatus status;
|
||||||
|
PyConfig config;
|
||||||
|
_PyConfig_InitCompatConfig(&config);
|
||||||
|
|
||||||
|
/* Call _PyConfig_InitPathConfig() */
|
||||||
|
status = PyConfig_Read(&config);
|
||||||
|
if (_PyStatus_EXCEPTION(status)) {
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
status = pathconfig_set_from_config(pathconfig, &config);
|
||||||
|
|
||||||
|
done:
|
||||||
|
PyConfig_Clear(&config);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
pathconfig_global_init(void)
|
pathconfig_global_init(void)
|
||||||
{
|
{
|
||||||
|
PyStatus status;
|
||||||
|
|
||||||
/* Initialize _Py_dll_path if needed */
|
/* Initialize _Py_dll_path if needed */
|
||||||
PyStatus status = _PyPathConfig_Init();
|
status = _PyPathConfig_Init();
|
||||||
if (_PyStatus_EXCEPTION(status)) {
|
if (_PyStatus_EXCEPTION(status)) {
|
||||||
Py_ExitStatusException(status);
|
Py_ExitStatusException(status);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_Py_path_config.module_search_path != NULL) {
|
if (_Py_path_config.module_search_path == NULL) {
|
||||||
/* Already initialized */
|
status = pathconfig_global_read(&_Py_path_config);
|
||||||
return;
|
if (_PyStatus_EXCEPTION(status)) {
|
||||||
|
Py_ExitStatusException(status);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* Global configuration already initialized */
|
||||||
}
|
}
|
||||||
|
|
||||||
PyConfig config;
|
assert(_Py_path_config.program_full_path != NULL);
|
||||||
_PyConfig_InitCompatConfig(&config);
|
assert(_Py_path_config.prefix != NULL);
|
||||||
|
assert(_Py_path_config.exec_prefix != NULL);
|
||||||
status = PyConfig_Read(&config);
|
assert(_Py_path_config.module_search_path != NULL);
|
||||||
if (_PyStatus_EXCEPTION(status)) {
|
assert(_Py_path_config.program_name != NULL);
|
||||||
goto error;
|
/* home can be NULL */
|
||||||
}
|
assert(_Py_path_config.base_executable != NULL);
|
||||||
|
|
||||||
status = pathconfig_global_init_from_config(&config);
|
|
||||||
if (_PyStatus_EXCEPTION(status)) {
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
PyConfig_Clear(&config);
|
|
||||||
return;
|
|
||||||
|
|
||||||
error:
|
|
||||||
PyConfig_Clear(&config);
|
|
||||||
Py_ExitStatusException(status);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -435,30 +455,27 @@ Py_SetPath(const wchar_t *path)
|
||||||
PyMemAllocatorEx old_alloc;
|
PyMemAllocatorEx old_alloc;
|
||||||
_PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
|
_PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
|
||||||
|
|
||||||
_PyPathConfig new_config;
|
/* Getting the program name calls pathconfig_global_init() */
|
||||||
new_config.program_full_path = _PyMem_RawWcsdup(Py_GetProgramName());
|
wchar_t *program_name = _PyMem_RawWcsdup(Py_GetProgramName());
|
||||||
int alloc_error = (new_config.program_full_path == NULL);
|
|
||||||
new_config.prefix = _PyMem_RawWcsdup(L"");
|
|
||||||
alloc_error |= (new_config.prefix == NULL);
|
|
||||||
new_config.exec_prefix = _PyMem_RawWcsdup(L"");
|
|
||||||
alloc_error |= (new_config.exec_prefix == NULL);
|
|
||||||
new_config.module_search_path = _PyMem_RawWcsdup(path);
|
|
||||||
alloc_error |= (new_config.module_search_path == NULL);
|
|
||||||
|
|
||||||
/* steal the home and program_name values (to leave them unchanged) */
|
PyMem_RawFree(_Py_path_config.program_full_path);
|
||||||
new_config.home = _Py_path_config.home;
|
PyMem_RawFree(_Py_path_config.prefix);
|
||||||
_Py_path_config.home = NULL;
|
PyMem_RawFree(_Py_path_config.exec_prefix);
|
||||||
new_config.program_name = _Py_path_config.program_name;
|
PyMem_RawFree(_Py_path_config.module_search_path);
|
||||||
_Py_path_config.program_name = NULL;
|
|
||||||
new_config.base_executable = _Py_path_config.base_executable;
|
|
||||||
_Py_path_config.base_executable = NULL;
|
|
||||||
|
|
||||||
pathconfig_clear(&_Py_path_config);
|
/* Copy program_name to program_full_path */
|
||||||
_Py_path_config = new_config;
|
_Py_path_config.program_full_path = program_name;
|
||||||
|
_Py_path_config.prefix = _PyMem_RawWcsdup(L"");
|
||||||
|
_Py_path_config.exec_prefix = _PyMem_RawWcsdup(L"");
|
||||||
|
_Py_path_config.module_search_path = _PyMem_RawWcsdup(path);
|
||||||
|
|
||||||
PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
|
PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
|
||||||
|
|
||||||
if (alloc_error) {
|
if (_Py_path_config.program_full_path == NULL
|
||||||
|
|| _Py_path_config.prefix == NULL
|
||||||
|
|| _Py_path_config.exec_prefix == NULL
|
||||||
|
|| _Py_path_config.module_search_path == NULL)
|
||||||
|
{
|
||||||
Py_FatalError("Py_SetPath() failed: out of memory");
|
Py_FatalError("Py_SetPath() failed: out of memory");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue