diff options
author | Victor Stinner <victor.stinner@gmail.com> | 2017-11-22 23:12:09 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-11-22 23:12:09 (GMT) |
commit | d4341109746aa15e1909e63b30b93b6133ffe401 (patch) | |
tree | 8982cc677ace3953484d4e4e34c8b154d0b9fb35 /Modules | |
parent | 82656276caf4cb889193572d2d14dbc5f3d2bdff (diff) | |
download | cpython-d4341109746aa15e1909e63b30b93b6133ffe401.zip cpython-d4341109746aa15e1909e63b30b93b6133ffe401.tar.gz cpython-d4341109746aa15e1909e63b30b93b6133ffe401.tar.bz2 |
bpo-32030: Add _PyCoreConfig.module_search_path_env (#4504)
Changes:
* Py_Main() initializes _PyCoreConfig.module_search_path_env from
the PYTHONPATH environment variable.
* PyInterpreterState_New() now initializes core_config and config
fields
* Compute sys.path a little bit ealier in
_Py_InitializeMainInterpreter() and new_interpreter()
* Add _Py_GetPathWithConfig() private function.
Diffstat (limited to 'Modules')
-rw-r--r-- | Modules/getpath.c | 61 | ||||
-rw-r--r-- | Modules/main.c | 74 |
2 files changed, 106 insertions, 29 deletions
diff --git a/Modules/getpath.c b/Modules/getpath.c index dd3387a..ad4a4e5 100644 --- a/Modules/getpath.c +++ b/Modules/getpath.c @@ -456,14 +456,12 @@ search_for_exec_prefix(wchar_t *argv0_path, wchar_t *home, } static void -calculate_path(void) +calculate_path(_PyCoreConfig *core_config) { extern wchar_t *Py_GetProgramName(void); static const wchar_t delimiter[2] = {DELIM, '\0'}; static const wchar_t separator[2] = {SEP, '\0'}; - char *_rtpypath = Py_GETENV("PYTHONPATH"); /* XXX use wide version on Windows */ - wchar_t *rtpypath = NULL; wchar_t *home = Py_GetPythonHome(); char *_path = getenv("PATH"); wchar_t *path_buffer = NULL; @@ -707,11 +705,22 @@ calculate_path(void) */ bufsz = 0; - if (_rtpypath && _rtpypath[0] != '\0') { - size_t rtpypath_len; - rtpypath = Py_DecodeLocale(_rtpypath, &rtpypath_len); - if (rtpypath != NULL) - bufsz += rtpypath_len + 1; + wchar_t *env_path = NULL; + if (core_config) { + if (core_config->module_search_path_env) { + bufsz += wcslen(core_config->module_search_path_env) + 1; + } + } + else { + char *env_pathb = Py_GETENV("PYTHONPATH"); + if (env_pathb && env_pathb[0] != '\0') { + size_t env_path_len; + env_path = Py_DecodeLocale(env_pathb, &env_path_len); + /* FIXME: handle decoding and memory error */ + if (env_path != NULL) { + bufsz += env_path_len + 1; + } + } } defpath = _pythonpath; @@ -742,12 +751,20 @@ calculate_path(void) } /* Run-time value of $PYTHONPATH goes first */ - if (rtpypath) { - wcscpy(buf, rtpypath); - wcscat(buf, delimiter); + buf[0] = '\0'; + if (core_config) { + if (core_config->module_search_path_env) { + wcscpy(buf, core_config->module_search_path_env); + wcscat(buf, delimiter); + } } - else - buf[0] = '\0'; + else { + if (env_path) { + wcscpy(buf, env_path); + wcscat(buf, delimiter); + } + } + PyMem_RawFree(env_path); /* Next is the default zip path */ wcscat(buf, zip_path); @@ -818,7 +835,6 @@ calculate_path(void) PyMem_RawFree(_prefix); PyMem_RawFree(_exec_prefix); PyMem_RawFree(lib_python); - PyMem_RawFree(rtpypath); } @@ -842,10 +858,19 @@ Py_SetPath(const wchar_t *path) } wchar_t * +_Py_GetPathWithConfig(_PyCoreConfig *core_config) +{ + if (!module_search_path) { + calculate_path(core_config); + } + return module_search_path; +} + +wchar_t * Py_GetPath(void) { if (!module_search_path) - calculate_path(); + calculate_path(NULL); return module_search_path; } @@ -853,7 +878,7 @@ wchar_t * Py_GetPrefix(void) { if (!module_search_path) - calculate_path(); + calculate_path(NULL); return prefix; } @@ -861,7 +886,7 @@ wchar_t * Py_GetExecPrefix(void) { if (!module_search_path) - calculate_path(); + calculate_path(NULL); return exec_prefix; } @@ -869,7 +894,7 @@ wchar_t * Py_GetProgramFullPath(void) { if (!module_search_path) - calculate_path(); + calculate_path(NULL); return progpath; } diff --git a/Modules/main.c b/Modules/main.c index e5e4f33..3bd93e3 100644 --- a/Modules/main.c +++ b/Modules/main.c @@ -399,6 +399,7 @@ typedef struct { _PyInitError err; /* PYTHONWARNINGS env var */ _Py_OptList env_warning_options; + /* PYTHONPATH env var */ int argc; wchar_t **argv; } _PyMain; @@ -441,6 +442,8 @@ pymain_free_impl(_PyMain *pymain) Py_CLEAR(pymain->main_importer_path); PyMem_RawFree(pymain->program_name); + PyMem_RawFree(pymain->core_config.module_search_path_env); + #ifdef __INSURE__ /* Insure++ is a memory analysis tool that aids in discovering * memory leaks and other memory problems. On Python exit, the @@ -502,15 +505,22 @@ error: static wchar_t* -pymain_strdup(_PyMain *pymain, wchar_t *str) +pymain_wstrdup(_PyMain *pymain, wchar_t *str) { size_t len = wcslen(str) + 1; /* +1 for NUL character */ - wchar_t *str2 = PyMem_RawMalloc(sizeof(wchar_t) * len); + if (len > (size_t)PY_SSIZE_T_MAX / sizeof(wchar_t)) { + pymain->err = INIT_NO_MEMORY(); + return NULL; + } + + size_t size = len * sizeof(wchar_t); + wchar_t *str2 = PyMem_RawMalloc(size); if (str2 == NULL) { pymain->err = INIT_NO_MEMORY(); return NULL; } - memcpy(str2, str, len * sizeof(wchar_t)); + + memcpy(str2, str, size); return str2; } @@ -518,7 +528,7 @@ pymain_strdup(_PyMain *pymain, wchar_t *str) static int pymain_optlist_append(_PyMain *pymain, _Py_OptList *list, wchar_t *str) { - wchar_t *str2 = pymain_strdup(pymain, str); + wchar_t *str2 = pymain_wstrdup(pymain, str); if (str2 == NULL) { return -1; } @@ -762,14 +772,12 @@ pymain_warnings_envvar(_PyMain *pymain) wchar_t *wp; if ((wp = _wgetenv(L"PYTHONWARNINGS")) && *wp != L'\0') { - wchar_t *buf, *warning, *context = NULL; + wchar_t *warning, *context = NULL; - buf = (wchar_t *)PyMem_RawMalloc((wcslen(wp) + 1) * sizeof(wchar_t)); + wchar_t *buf = pymain_wstrdup(pymain, wp); if (buf == NULL) { - pymain->err = INIT_NO_MEMORY(); return -1; } - wcscpy(buf, wp); for (warning = wcstok_s(buf, L",", &context); warning != NULL; warning = wcstok_s(NULL, L",", &context)) { @@ -805,12 +813,11 @@ pymain_warnings_envvar(_PyMain *pymain) if (len == (size_t)-2) { pymain->err = _Py_INIT_ERR("failed to decode " "PYTHONWARNINGS"); - return -1; } else { pymain->err = INIT_NO_MEMORY(); - return -1; } + return -1; } if (pymain_optlist_append(pymain, &pymain->env_warning_options, warning) < 0) { @@ -929,7 +936,7 @@ pymain_get_program_name(_PyMain *pymain) if (pymain->program_name == NULL) { /* Use argv[0] by default */ - pymain->program_name = pymain_strdup(pymain, pymain->argv[0]); + pymain->program_name = pymain_wstrdup(pymain, pymain->argv[0]); if (pymain->program_name == NULL) { return -1; } @@ -1363,6 +1370,48 @@ pymain_set_flags_from_env(_PyMain *pymain) static int +pymain_init_pythonpath(_PyMain *pymain) +{ + if (Py_IgnoreEnvironmentFlag) { + return 0; + } + +#ifdef MS_WINDOWS + wchar_t *path = _wgetenv(L"PYTHONPATH"); + if (!path || path[0] == '\0') { + return 0; + } + + wchar_t *path2 = pymain_wstrdup(pymain, path); + if (path2 == NULL) { + return -1; + } + + pymain->core_config.module_search_path_env = path2; +#else + char *path = pymain_get_env_var("PYTHONPATH"); + if (!path) { + return 0; + } + + size_t len; + wchar_t *wpath = Py_DecodeLocale(path, &len); + if (!wpath) { + if (len == (size_t)-2) { + pymain->err = _Py_INIT_ERR("failed to decode PYTHONHOME"); + } + else { + pymain->err = INIT_NO_MEMORY(); + } + return -1; + } + pymain->core_config.module_search_path_env = wpath; +#endif + return 0; +} + + +static int pymain_parse_envvars(_PyMain *pymain) { _PyCoreConfig *core_config = &pymain->core_config; @@ -1383,6 +1432,9 @@ pymain_parse_envvars(_PyMain *pymain) return -1; } core_config->allocator = Py_GETENV("PYTHONMALLOC"); + if (pymain_init_pythonpath(pymain) < 0) { + return -1; + } /* -X options */ if (pymain_get_xoption(pymain, L"showrefcount")) { |