8000 [3.12] gh-109853: Fix sys.path[0] For Subinterpreters (gh-109994) by ericsnowcurrently · Pull Request #110701 · python/cpython · GitHub
[go: up one dir, main page]

Skip to content

[3.12] gh-109853: Fix sys.path[0] For Subinterpreters (gh-109994) #110701

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Do not modify PyConfig. Add sys_path_0 to _PyRuntimeState instead.
  • Loading branch information
ericsnowcurrently committed Oct 11, 2023
commit d47338039acd800d71b8e524d3ecef17bf5ca081
3 changes: 0 additions & 3 deletions Include/cpython/initconfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -205,9 +205,6 @@ typedef struct PyConfig {
wchar_t *run_module;
wchar_t *run_filename;

/* --- Set by Py_Main() -------------------------- */
wchar_t *sys_path_0;

/* --- Private fields ---------------------------- */

// Install importlib? If equals to 0, importlib is not initialized at all.
Expand Down
5 changes: 5 additions & 0 deletions Include/internal/pycore_runtime.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,11 @@ typedef struct pyruntimestate {

unsi 8000 gned long main_thread;

/* The value to use for sys.path[0] in new subinterpreters.
Normally this would be part of the PyConfig struct. However,
we cannot add it there in 3.12 since that's an ABI change. */
wchar_t *sys_path_0;

/* ---------- IMPORTANT ---------------------------
The fields above this line are declared as early as
possible to facilitate out-of-process observability
Expand Down
3 changes: 0 additions & 3 deletions Lib/test/test_embed.py
Original file line number Diff line number Diff line change
Expand Up @@ -500,7 +500,6 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase):
'run_command': None,
'run_module': None,
'run_filename': None,
'sys_path_0': None,

'_install_importlib': 1,
'check_hash_pycs_mode': 'default',
Expand Down Expand Up @@ -1120,7 +1119,6 @@ def test_init_run_main(self):
'program_name': './python3',
'run_command': code + '\n',
'parse_argv': 2,
'sys_path_0': '',
}
self.check_all_configs("test_init_run_main", config, api=API_PYTHON)

Expand All @@ -1136,7 +1134,6 @@ def test_init_main(self):
'run_command': code + '\n',
'parse_argv': 2,
'_init_main': 0,
'sys_path_0': '',
}
self.check_all_configs("test_init_main", config,
api=API_PYTHON,
Expand Down
13 changes: 8 additions & 5 deletions Modules/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -559,10 +559,10 @@ pymain_run_python(int *exitcode)
goto error;
}

// XXX Calculate config->sys_path_0 in getpath.py.
// XXX Calculate runtime->sys_path_0 in getpath.py.
// The tricky part is that we can't check the path importers yet
// at that point.
assert(config->sys_path_0 == NULL);
assert(interp->runtime->sys_path_0 == NULL);

if (config->run_filename != NULL) {
/* If filename is a package (ex: directory or ZIP file) which contains
Expand Down Expand Up @@ -592,17 +592,20 @@ pymain_run_python(int *exitcode)
Py_CLEAR(path0);
}
}
// XXX Apply config->sys_path_0 in init_interp_main(). We have
// XXX Apply runtime->sys_path_0 in init_interp_main(). We have
// to be sure to get readline/rlcompleter imported at the correct time.
if (path0 != NULL) {
wchar_t *wstr = PyUnicode_AsWideCharString(path0, NULL);
if (wstr == NULL) {
Py_DECREF(path0);
goto error;
}
config->sys_path_0 = _PyMem_RawWcsdup(wstr);
PyMemAllocatorEx old_alloc;
_PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
interp->runtime->sys_path_0 = _PyMem_RawWcsdup(wstr);
PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
PyMem_Free(wstr);
if (config->sys_path_0 == NULL) {
if (interp->runtime->sys_path_0 == NULL) {
Py_DECREF(path0);
goto error;
}
Expand Down
5 changes: 0 additions & 5 deletions Python/initconfig.c
Original file line number Diff line number Diff line change
Expand Up @@ -739,7 +739,6 @@ PyConfig_Clear(PyConfig *config)
CLEAR(config->exec_prefix);
CLEAR(config->base_exec_prefix);
CLEAR(config->platlibdir);
CLEAR(config->sys_path_0);

CLEAR(config->filesystem_encoding);
CLEAR(config->filesystem_errors);
Expand Down Expand Up @@ -994,7 +993,6 @@ _PyConfig_Copy(PyConfig *config, const PyConfig *config2)
COPY_WSTR_ATTR(exec_prefix);
COPY_WSTR_ATTR(base_exec_prefix);
COPY_WSTR_ATTR(platlibdir);
COPY_WSTR_ATTR(sys_path_0);

COPY_ATTR(site_import);
COPY_ATTR(bytes_warning);
Expand Down Expand Up @@ -1104,7 +1102,6 @@ _PyConfig_AsDict(const PyConfig *config)
SET_ITEM_WSTR(exec_prefix);
SET_ITEM_WSTR(base_exec_prefix);
SET_ITEM_WSTR(platlibdir);
SET_ITEM_WSTR(sys_path_0);< 628C /td>
SET_ITEM_INT(site_import);
SET_ITEM_INT(bytes_warning);
SET_ITEM_INT(warn_default_encoding);
Expand Down Expand Up @@ -1406,7 +1403,6 @@ _PyConfig_FromDict(PyConfig *config, PyObject *dict)
GET_WSTR_OPT(pythonpath_env);
GET_WSTR_OPT(home);
GET_WSTR(platlibdir);
GET_WSTR(sys_path_0);

// Path configuration output
GET_UINT(module_search_paths_set);
Expand Down Expand Up @@ -3169,7 +3165,6 @@ _Py_DumpPathConfig(PyThreadState *tstate)
PySys_WriteStderr(" import site = %i\n", config->site_import);
PySys_WriteStderr(" is in build tree = %i\n", config->_is_python_build);
DUMP_CONFIG("stdlib dir", stdlib_dir);
DUMP_CONFIG("sys.path[0]", sys_path_0);
#undef DUMP_CONFIG

#define DUMP_SYS(NAME) \
Expand Down
5 changes: 3 additions & 2 deletions Python/pylifecycle.c
Original file line number Diff line number Diff line change
Expand Up @@ -1202,8 +1202,9 @@ init_interp_main(PyThreadState *tstate)

if (!is_main_interp) {
// The main interpreter is handled in Py_Main(), for now.
if (config->sys_path_0 != NULL) {
PyObject *path0 = PyUnicode_FromWideChar(config->sys_path_0, -1);
wchar_t *sys_path_0 = interp->runtime->sys_path_0;
if (sys_path_0 != NULL) {
PyObject *path0 = PyUnicode_FromWideChar(sys_path_0, -1);
if (path0 == NULL) {
return _PyStatus_ERR("can't initialize sys.path[0]");
}
Expand Down
4 changes: 4 additions & 0 deletions Python/pystate.c
Original file line number Diff line number Diff line change
Expand Up @@ -524,6 +524,10 @@ _PyRuntimeState_Fini(_PyRuntimeState *runtime)
}

#undef FREE_LOCK
if (runtime->sys_path_0 != NULL) {
PyMem_RawFree(runtime->sys_path_0);
runtime->sys_path_0 = NULL;
}
PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
}

Expand Down
0