Skip to content

Commit e851049

Browse files
authored
bpo-34725: Adds _Py_SetProgramFullPath so embedders may override sys.executable (GH-9861)
1 parent d1a97b3 commit e851049

File tree

4 files changed

+50
-0
lines changed

4 files changed

+50
-0
lines changed

Include/pylifecycle.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ PyAPI_FUNC(void) Py_SetPythonHome(const wchar_t *);
4444
PyAPI_FUNC(wchar_t *) Py_GetPythonHome(void);
4545

4646
#ifndef Py_LIMITED_API
47+
PyAPI_FUNC(void) _Py_SetProgramFullPath(const wchar_t *);
48+
4749
/* Only used by applications that embed the interpreter and need to
4850
* override the standard encoding determination mechanism
4951
*/
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Adds _Py_SetProgramFullPath so embedders may override sys.executable

Modules/main.c

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1206,6 +1206,25 @@ config_init_program_name(_PyCoreConfig *config)
12061206
}
12071207

12081208

1209+
static _PyInitError
1210+
config_init_executable(_PyCoreConfig *config)
1211+
{
1212+
assert(config->executable == NULL);
1213+
1214+
/* If Py_SetProgramFullPath() was called, use its value */
1215+
const wchar_t *program_full_path = _Py_path_config.program_full_path;
1216+
if (program_full_path != NULL) {
1217+
config->executable = _PyMem_RawWcsdup(program_full_path);
1218+
if (config->executable == NULL) {
1219+
return _Py_INIT_NO_MEMORY();
1220+
}
1221+
return _Py_INIT_OK();
1222+
}
1223+
1224+
return _Py_INIT_OK();
1225+
}
1226+
1227+
12091228
static void
12101229
pymain_header(_PyMain *pymain)
12111230
{
@@ -2350,6 +2369,13 @@ _PyCoreConfig_Read(_PyCoreConfig *config)
23502369
}
23512370
}
23522371

2372+
if (config->executable == NULL) {
2373+
err = config_init_executable(config);
2374+
if (_Py_INIT_FAILED(err)) {
2375+
return err;
2376+
}
2377+
}
2378+
23532379
if (config->utf8_mode < 0 || config->coerce_c_locale < 0) {
23542380
config_init_locale(config);
23552381
}

Python/pathconfig.c

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,27 @@ Py_SetProgramName(const wchar_t *program_name)
205205
}
206206

207207

208+
void
209+
_Py_SetProgramFullPath(const wchar_t *program_full_path)
210+
{
211+
if (program_full_path == NULL || program_full_path[0] == L'\0') {
212+
return;
213+
}
214+
215+
PyMemAllocatorEx old_alloc;
216+
_PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
217+
218+
PyMem_RawFree(_Py_path_config.program_full_path);
219+
_Py_path_config.program_full_path = _PyMem_RawWcsdup(program_full_path);
220+
221+
PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
222+
223+
if (_Py_path_config.program_full_path == NULL) {
224+
Py_FatalError("Py_SetProgramFullPath() failed: out of memory");
225+
}
226+
}
227+
228+
208229
wchar_t *
209230
Py_GetPath(void)
210231
{

0 commit comments

Comments
 (0)