bpo-36236: Handle removed cwd at Python init (GH-12424)
At Python initialization, the current directory is no longer prepended to sys.path if it has been removed. Rename _PyPathConfig_ComputeArgv0() to _PyPathConfig_ComputeSysPath0() to avoid confusion between argv[0] and sys.path[0].
This commit is contained in:
parent
f5f336a819
commit
dcf617152e
|
@ -44,7 +44,9 @@ PyAPI_FUNC(_PyInitError) _PyPathConfig_SetGlobal(
|
||||||
PyAPI_FUNC(_PyInitError) _PyPathConfig_Calculate_impl(
|
PyAPI_FUNC(_PyInitError) _PyPathConfig_Calculate_impl(
|
||||||
_PyPathConfig *config,
|
_PyPathConfig *config,
|
||||||
const _PyCoreConfig *core_config);
|
const _PyCoreConfig *core_config);
|
||||||
PyAPI_FUNC(PyObject*) _PyPathConfig_ComputeArgv0(const _PyWstrList *argv);
|
PyAPI_FUNC(int) _PyPathConfig_ComputeSysPath0(
|
||||||
|
const _PyWstrList *argv,
|
||||||
|
PyObject **path0);
|
||||||
PyAPI_FUNC(int) _Py_FindEnvConfigValue(
|
PyAPI_FUNC(int) _Py_FindEnvConfigValue(
|
||||||
FILE *env_file,
|
FILE *env_file,
|
||||||
const wchar_t *key,
|
const wchar_t *key,
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
At Python initialization, the current directory is no longer prepended to
|
||||||
|
:data:`sys.path` if it has been removed.
|
|
@ -780,18 +780,20 @@ pymain_run_python(PyInterpreterState *interp, int *exitcode)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (!config->preconfig.isolated) {
|
else if (!config->preconfig.isolated) {
|
||||||
PyObject *path0 = _PyPathConfig_ComputeArgv0(&config->argv);
|
PyObject *path0 = NULL;
|
||||||
if (path0 == NULL) {
|
if (_PyPathConfig_ComputeSysPath0(&config->argv, &path0)) {
|
||||||
err = _Py_INIT_NO_MEMORY();
|
if (path0 == NULL) {
|
||||||
goto done;
|
err = _Py_INIT_NO_MEMORY();
|
||||||
}
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
if (pymain_sys_path_add_path0(interp, path0) < 0) {
|
if (pymain_sys_path_add_path0(interp, path0) < 0) {
|
||||||
|
Py_DECREF(path0);
|
||||||
|
err = _Py_INIT_EXIT(1);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
Py_DECREF(path0);
|
Py_DECREF(path0);
|
||||||
err = _Py_INIT_EXIT(1);
|
|
||||||
goto done;
|
|
||||||
}
|
}
|
||||||
Py_DECREF(path0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PyCompilerFlags cf = {.cf_flags = 0, .cf_feature_version = PY_MINOR_VERSION};
|
PyCompilerFlags cf = {.cf_flags = 0, .cf_feature_version = PY_MINOR_VERSION};
|
||||||
|
|
|
@ -566,9 +566,18 @@ Py_GetProgramName(void)
|
||||||
return _Py_path_config.program_name;
|
return _Py_path_config.program_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Compute argv[0] which will be prepended to sys.argv */
|
/* Compute module search path from argv[0] or the current working
|
||||||
PyObject*
|
directory ("-m module" case) which will be prepended to sys.argv:
|
||||||
_PyPathConfig_ComputeArgv0(const _PyWstrList *argv)
|
sys.path[0].
|
||||||
|
|
||||||
|
Return 1 if the path is correctly resolved, but *path0_p can be NULL
|
||||||
|
if the Unicode object fail to be created.
|
||||||
|
|
||||||
|
Return 0 if it fails to resolve the full path (and *path0_p will be NULL),
|
||||||
|
for example if the current working directory has been removed (bpo-36236).
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
_PyPathConfig_ComputeSysPath0(const _PyWstrList *argv, PyObject **path0_p)
|
||||||
{
|
{
|
||||||
assert(_PyWstrList_CheckConsistency(argv));
|
assert(_PyWstrList_CheckConsistency(argv));
|
||||||
|
|
||||||
|
@ -588,6 +597,8 @@ _PyPathConfig_ComputeArgv0(const _PyWstrList *argv)
|
||||||
wchar_t fullpath[MAX_PATH];
|
wchar_t fullpath[MAX_PATH];
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
assert(*path0_p == NULL);
|
||||||
|
|
||||||
if (argv->length > 0) {
|
if (argv->length > 0) {
|
||||||
argv0 = argv->items[0];
|
argv0 = argv->items[0];
|
||||||
have_module_arg = (wcscmp(argv0, L"-m") == 0);
|
have_module_arg = (wcscmp(argv0, L"-m") == 0);
|
||||||
|
@ -595,14 +606,17 @@ _PyPathConfig_ComputeArgv0(const _PyWstrList *argv)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (have_module_arg) {
|
if (have_module_arg) {
|
||||||
#if defined(HAVE_REALPATH) || defined(MS_WINDOWS)
|
#if defined(HAVE_REALPATH) || defined(MS_WINDOWS)
|
||||||
_Py_wgetcwd(fullpath, Py_ARRAY_LENGTH(fullpath));
|
if (!_Py_wgetcwd(fullpath, Py_ARRAY_LENGTH(fullpath))) {
|
||||||
|
*path0_p = NULL;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
argv0 = fullpath;
|
argv0 = fullpath;
|
||||||
n = wcslen(argv0);
|
n = wcslen(argv0);
|
||||||
#else
|
#else
|
||||||
argv0 = L".";
|
argv0 = L".";
|
||||||
n = 1;
|
n = 1;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_READLINK
|
#ifdef HAVE_READLINK
|
||||||
|
@ -675,7 +689,8 @@ _PyPathConfig_ComputeArgv0(const _PyWstrList *argv)
|
||||||
}
|
}
|
||||||
#endif /* All others */
|
#endif /* All others */
|
||||||
|
|
||||||
return PyUnicode_FromWideChar(argv0, n);
|
*path0_p = PyUnicode_FromWideChar(argv0, n);
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -2781,19 +2781,21 @@ PySys_SetArgvEx(int argc, wchar_t **argv, int updatepath)
|
||||||
/* If argv[0] is not '-c' nor '-m', prepend argv[0] to sys.path.
|
/* If argv[0] is not '-c' nor '-m', prepend argv[0] to sys.path.
|
||||||
If argv[0] is a symlink, use the real path. */
|
If argv[0] is a symlink, use the real path. */
|
||||||
const _PyWstrList argv_list = {.length = argc, .items = argv};
|
const _PyWstrList argv_list = {.length = argc, .items = argv};
|
||||||
PyObject *argv0 = _PyPathConfig_ComputeArgv0(&argv_list);
|
PyObject *path0 = NULL;
|
||||||
if (argv0 == NULL) {
|
if (_PyPathConfig_ComputeSysPath0(&argv_list, &path0)) {
|
||||||
Py_FatalError("can't compute path0 from argv");
|
if (path0 == NULL) {
|
||||||
}
|
Py_FatalError("can't compute path0 from argv");
|
||||||
|
|
||||||
PyObject *sys_path = _PySys_GetObjectId(&PyId_path);
|
|
||||||
if (sys_path != NULL) {
|
|
||||||
if (PyList_Insert(sys_path, 0, argv0) < 0) {
|
|
||||||
Py_DECREF(argv0);
|
|
||||||
Py_FatalError("can't prepend path0 to sys.path");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PyObject *sys_path = _PySys_GetObjectId(&PyId_path);
|
||||||
|
if (sys_path != NULL) {
|
||||||
|
if (PyList_Insert(sys_path, 0, path0) < 0) {
|
||||||
|
Py_DECREF(path0);
|
||||||
|
Py_FatalError("can't prepend path0 to sys.path");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Py_DECREF(path0);
|
||||||
}
|
}
|
||||||
Py_DECREF(argv0);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue