Skip to content

Commit f7959a9

Browse files
authored
bpo-36236: Handle removed cwd at Python init (GH-12450)
At Python initialization, the current directory is no longer prepended to sys.path if it has been removed.
1 parent 935250d commit f7959a9

File tree

5 files changed

+36
-36
lines changed

5 files changed

+36
-36
lines changed

Include/pylifecycle.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,9 @@ PyAPI_FUNC(wchar_t *) Py_GetExecPrefix(void);
139139
PyAPI_FUNC(wchar_t *) Py_GetPath(void);
140140
#ifdef Py_BUILD_CORE
141141
PyAPI_FUNC(_PyInitError) _PyPathConfig_Init(const _PyCoreConfig *core_config);
142-
PyAPI_FUNC(PyObject*) _PyPathConfig_ComputeArgv0(int argc, wchar_t **argv);
142+
PyAPI_FUNC(int) _PyPathConfig_ComputeArgv0(
143+
int argc, wchar_t **argv,
144+
PyObject **argv0_p);
143145
PyAPI_FUNC(int) _Py_FindEnvConfigValue(
144146
FILE *env_file,
145147
const wchar_t *key,
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
At Python initialization, the current directory is no longer prepended to
2+
:data:`sys.path` if it has been removed.

Modules/main.c

Lines changed: 18 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1339,29 +1339,6 @@ _Py_wstrlist_as_pylist(int len, wchar_t **list)
13391339
}
13401340

13411341

1342-
static int
1343-
pymain_compute_path0(_PyMain *pymain, _PyCoreConfig *config, PyObject **path0)
1344-
{
1345-
if (pymain->main_importer_path != NULL) {
1346-
/* Let pymain_run_main_from_importer() adjust sys.path[0] later */
1347-
*path0 = NULL;
1348-
return 0;
1349-
}
1350-
1351-
if (Py_IsolatedFlag) {
1352-
*path0 = NULL;
1353-
return 0;
1354-
}
1355-
1356-
*path0 = _PyPathConfig_ComputeArgv0(config->argc, config->argv);
1357-
if (*path0 == NULL) {
1358-
pymain->err = _Py_INIT_NO_MEMORY();
1359-
return -1;
1360-
}
1361-
return 0;
1362-
}
1363-
1364-
13651342
static int
13661343
pymain_update_sys_path(_PyMain *pymain, PyObject *path0)
13671344
{
@@ -2845,18 +2822,29 @@ pymain_init_sys_path(_PyMain *pymain, _PyCoreConfig *config)
28452822
pymain->main_importer_path = pymain_get_importer(pymain->filename);
28462823
}
28472824

2848-
PyObject *path0;
2849-
if (pymain_compute_path0(pymain, config, &path0) < 0) {
2825+
if (pymain->main_importer_path != NULL) {
2826+
/* Let pymain_run_main_from_importer() adjust sys.path[0] later */
2827+
return 0;
2828+
}
2829+
2830+
if (Py_IsolatedFlag) {
2831+
return 0;
2832+
}
2833+
2834+
PyObject *path0 = NULL;
2835+
if (!_PyPathConfig_ComputeArgv0(config->argc, config->argv, &path0)) {
2836+
return 0;
2837+
}
2838+
if (path0 == NULL) {
2839+
pymain->err = _Py_INIT_NO_MEMORY();
28502840
return -1;
28512841
}
28522842

2853-
if (path0 != NULL) {
2854-
if (pymain_update_sys_path(pymain, path0) < 0) {
2855-
Py_DECREF(path0);
2856-
return -1;
2857-
}
2843+
if (pymain_update_sys_path(pymain, path0) < 0) {
28582844
Py_DECREF(path0);
2845+
return -1;
28592846
}
2847+
Py_DECREF(path0);
28602848
return 0;
28612849
}
28622850

Python/pathconfig.c

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -278,8 +278,8 @@ Py_GetProgramName(void)
278278
}
279279

280280
/* Compute argv[0] which will be prepended to sys.argv */
281-
PyObject*
282-
_PyPathConfig_ComputeArgv0(int argc, wchar_t **argv)
281+
int
282+
_PyPathConfig_ComputeArgv0(int argc, wchar_t **argv, PyObject **argv0_p)
283283
{
284284
wchar_t *argv0;
285285
wchar_t *p = NULL;
@@ -297,6 +297,8 @@ _PyPathConfig_ComputeArgv0(int argc, wchar_t **argv)
297297
wchar_t fullpath[MAX_PATH];
298298
#endif
299299

300+
assert(*argv0_p == NULL);
301+
300302
argv0 = argv[0];
301303
if (argc > 0 && argv0 != NULL) {
302304
have_module_arg = (wcscmp(argv0, L"-m") == 0);
@@ -305,7 +307,9 @@ _PyPathConfig_ComputeArgv0(int argc, wchar_t **argv)
305307

306308
if (have_module_arg) {
307309
#if defined(HAVE_REALPATH) || defined(MS_WINDOWS)
308-
_Py_wgetcwd(fullpath, Py_ARRAY_LENGTH(fullpath));
310+
if (!_Py_wgetcwd(fullpath, Py_ARRAY_LENGTH(fullpath))) {
311+
return 0;
312+
}
309313
argv0 = fullpath;
310314
n = wcslen(argv0);
311315
#else
@@ -384,7 +388,8 @@ _PyPathConfig_ComputeArgv0(int argc, wchar_t **argv)
384388
}
385389
#endif /* All others */
386390

387-
return PyUnicode_FromWideChar(argv0, n);
391+
*argv0_p = PyUnicode_FromWideChar(argv0, n);
392+
return 1;
388393
}
389394

390395

Python/sysmodule.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2615,7 +2615,10 @@ PySys_SetArgvEx(int argc, wchar_t **argv, int updatepath)
26152615
if (updatepath) {
26162616
/* If argv[0] is not '-c' nor '-m', prepend argv[0] to sys.path.
26172617
If argv[0] is a symlink, use the real path. */
2618-
PyObject *argv0 = _PyPathConfig_ComputeArgv0(argc, argv);
2618+
PyObject *argv0 = NULL;
2619+
if (!_PyPathConfig_ComputeArgv0(argc, argv, &argv0)) {
2620+
return;
2621+
}
26192622
if (argv0 == NULL) {
26202623
Py_FatalError("can't compute path0 from argv");
26212624
}

0 commit comments

Comments
 (0)