bpo-32030: Add _PyMainInterpreterConfig.pythonhome by vstinner · Pull Request #4513 · python/cpython · GitHub
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
7 changes: 6 additions & 1 deletion Include/pylifecycle.h
5 changes: 4 additions & 1 deletion Include/pystate.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,12 +61,15 @@ typedef struct {
typedef struct {
int install_signal_handlers;
wchar_t *module_search_path_env; /* PYTHONPATH environment variable */
wchar_t *pythonhome; /* PYTHONHOME environment variable,
see also Py_SetPythonHome(). */
} _PyMainInterpreterConfig;

#define _PyMainInterpreterConfig_INIT \
(_PyMainInterpreterConfig){\
.install_signal_handlers = -1, \
.module_search_path_env = NULL}
.module_search_path_env = NULL, \
.pythonhome = NULL}

typedef struct _is {

Expand Down
3 changes: 3 additions & 0 deletions Include/warnings.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ extern "C" {
#ifndef Py_LIMITED_API
PyAPI_FUNC(PyObject*) _PyWarnings_Init(void);
#endif
#ifdef Py_BUILD_CORE
PyAPI_FUNC(PyObject*) _PyWarnings_InitWithConfig(const _PyCoreConfig *config);
#endif

PyAPI_FUNC(int) PyErr_WarnEx(
PyObject *category,
Expand Down
6 changes: 3 additions & 3 deletions Modules/getpath.c
Original file line number Diff line number Diff line change
Expand Up @@ -456,13 +456,13 @@ search_for_exec_prefix(wchar_t *argv0_path, wchar_t *home,
}

static void
calculate_path(_PyMainInterpreterConfig *config)
calculate_path(const _PyMainInterpreterConfig *config)
{
extern wchar_t *Py_GetProgramName(void);

static const wchar_t delimiter[2] = {DELIM, '\0'};
static const wchar_t separator[2] = {SEP, '\0'};
wchar_t *home = Py_GetPythonHome();
wchar_t *home = _Py_GetPythonHomeWithConfig(config);
char *_path = getenv("PATH");
wchar_t *path_buffer = NULL;
wchar_t *path = NULL;
Expand Down Expand Up @@ -858,7 +858,7 @@ Py_SetPath(const wchar_t *path)
}

wchar_t *
_Py_GetPathWithConfig(_PyMainInterpreterConfig *config)
_Py_GetPathWithConfig(const _PyMainInterpreterConfig *config)
{
if (!module_search_path) {
calculate_path(config);
Expand Down
81 changes: 67 additions & 14 deletions Modules/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -400,7 +400,6 @@ typedef struct {
_PyInitError err;
/* PYTHONWARNINGS env var */
_Py_OptList env_warning_options;
/* PYTHONPATH env var */
int argc;
wchar_t **argv;
} _PyMain;
Expand Down Expand Up @@ -1368,47 +1367,98 @@ pymain_set_flags_from_env(_PyMain *pymain)


static int
pymain_init_pythonpath(_PyMain *pymain)
pymain_get_env_var_dup(_PyMain *pymain, wchar_t **dest,
wchar_t *wname, char *name)
{
if (Py_IgnoreEnvironmentFlag) {
*dest = NULL;
return 0;
}

#ifdef MS_WINDOWS
wchar_t *path = _wgetenv(L"PYTHONPATH");
if (!path || path[0] == '\0') {
wchar_t *var = _wgetenv(wname);
if (!var || var[0] == '\0') {
*dest = NULL;
return 0;
}

wchar_t *path2 = pymain_wstrdup(pymain, path);
if (path2 == NULL) {
wchar_t *copy = pymain_wstrdup(pymain, var);
if (copy == NULL) {
return -1;
}

pymain->config.module_search_path_env = path2;
*dest = copy;
#else
char *path = pymain_get_env_var("PYTHONPATH");
if (!path) {
char *var = getenv(name);
if (!var || var[0] == '\0') {
*dest = NULL;
return 0;
}

size_t len;
wchar_t *wpath = Py_DecodeLocale(path, &len);
if (!wpath) {
wchar_t *wvar = Py_DecodeLocale(var, &len);
if (!wvar) {
if (len == (size_t)-2) {
pymain->err = _Py_INIT_ERR("failed to decode PYTHONHOME");
/* don't set pymain->err */
return -2;
}
else {
pymain->err = INIT_NO_MEMORY();
return -1;
}
return -1;
}
pymain->config.module_search_path_env = wpath;
*dest = wvar;
#endif
return 0;
}


static int
pymain_init_pythonpath(_PyMain *pymain)
{
wchar_t *path;
int res = pymain_get_env_var_dup(pymain, &path,
L"PYTHONPATH", "PYTHONPATH");
if (res < 0) {
if (res == -2) {
pymain->err = _Py_INIT_ERR("failed to decode PYTHONPATH");
}
return -1;
}
pymain->config.module_search_path_env = path;
return 0;
}


static int
pymain_init_pythonhome(_PyMain *pymain)
{
wchar_t *home;

home = Py_GetPythonHome();
if (home) {
/* Py_SetPythonHome() has been called before Py_Main(),
use its value */
pymain->config.pythonhome = pymain_wstrdup(pymain, home);
if (pymain->config.pythonhome == NULL) {
return -1;
}
return 0;
}

int res = pymain_get_env_var_dup(pymain, &home,
L"PYTHONHOME", "PYTHONHOME");
if (res < 0) {
if (res == -2) {
pymain->err = _Py_INIT_ERR("failed to decode PYTHONHOME");
}
return -1;
}
pymain->config.pythonhome = home;
return 0;
}


static int
pymain_parse_envvars(_PyMain *pymain)
{
Expand All @@ -1433,6 +1483,9 @@ pymain_parse_envvars(_PyMain *pymain)
if (pymain_init_pythonpath(pymain) < 0) {
return -1;
}
if (pymain_init_pythonhome(pymain) < 0) {
return -1;
}

/* -X options */
if (pymain_get_xoption(pymain, L"showrefcount")) {
Expand Down
6 changes: 3 additions & 3 deletions PC/getpathp.c
Original file line number Diff line number Diff line change
Expand Up @@ -624,12 +624,12 @@ read_pth_file(const wchar_t *path, wchar_t *prefix, int *isolated, int *nosite)


static void
calculate_path(_PyMainInterpreterConfig *config)
calculate_path(const _PyMainInterpreterConfig *config)
{
wchar_t argv0_path[MAXPATHLEN+1];
wchar_t *buf;
size_t bufsz;
wchar_t *pythonhome = Py_GetPythonHome();
wchar_t *pythonhome = _Py_GetPythonHomeWithConfig(config);
wchar_t *envpath = NULL;

int skiphome, skipdefault;
Expand Down Expand Up @@ -899,7 +899,7 @@ Py_SetPath(const wchar_t *path)
}

wchar_t *
_Py_GetPathWithConfig(_PyMainInterpreterConfig *config)
_Py_GetPathWithConfig(const _PyMainInterpreterConfig *config)
{
if (!module_search_path) {
calculate_path(config);
Expand Down
20 changes: 14 additions & 6 deletions Python/_warnings.c
Original file line number Diff line number Diff line change
Expand Up @@ -1185,10 +1185,9 @@ create_filter(PyObject *category, const char *action)
}

static PyObject *
init_filters(void)
init_filters(const _PyCoreConfig *config)
{
PyInterpreterState *interp = PyThreadState_GET()->interp;
int dev_mode = interp->core_config.dev_mode;
int dev_mode = config->dev_mode;

Py_ssize_t count = 2;
if (dev_mode) {
Expand Down Expand Up @@ -1264,8 +1263,8 @@ static struct PyModuleDef warningsmodule = {
};


PyMODINIT_FUNC
_PyWarnings_Init(void)
PyObject*
_PyWarnings_InitWithConfig(const _PyCoreConfig *config)
{
PyObject *m;

Expand All @@ -1274,7 +1273,7 @@ _PyWarnings_Init(void)
return NULL;

if (_PyRuntime.warnings.filters == NULL) {
_PyRuntime.warnings.filters = init_filters();
_PyRuntime.warnings.filters = init_filters(config);
if (_PyRuntime.warnings.filters == NULL)
return NULL;
}
Expand Down Expand Up @@ -1305,3 +1304,12 @@ _PyWarnings_Init(void)
_PyRuntime.warnings.filters_version = 0;
return m;
}


PyMODINIT_FUNC
_PyWarnings_Init(void)
{
PyInterpreterState *interp = PyThreadState_GET()->interp;
const _PyCoreConfig *config = &interp->core_config;
return _PyWarnings_InitWithConfig(config);
}
49 changes: 35 additions & 14 deletions Python/pylifecycle.c