PyAPI_FUNC(void) Py_SetPythonHome(wchar_t *);
PyAPI_FUNC(wchar_t *) Py_GetPythonHome(void);
+#ifdef Py_BUILD_CORE
+PyAPI_FUNC(wchar_t *) _Py_GetPythonHomeWithConfig(
+ const _PyMainInterpreterConfig *config);
+#endif
#ifndef Py_LIMITED_API
/* Only used by applications that embed the interpreter and need to
PyAPI_FUNC(wchar_t *) Py_GetExecPrefix(void);
PyAPI_FUNC(wchar_t *) Py_GetPath(void);
#ifdef Py_BUILD_CORE
-PyAPI_FUNC(wchar_t *) _Py_GetPathWithConfig(_PyMainInterpreterConfig *config);
+PyAPI_FUNC(wchar_t *) _Py_GetPathWithConfig(
+ const _PyMainInterpreterConfig *config);
#endif
PyAPI_FUNC(void) Py_SetPath(const wchar_t *);
#ifdef MS_WINDOWS
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 {
#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,
}
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;
}
wchar_t *
-_Py_GetPathWithConfig(_PyMainInterpreterConfig *config)
+_Py_GetPathWithConfig(const _PyMainInterpreterConfig *config)
{
if (!module_search_path) {
calculate_path(config);
_PyInitError err;
/* PYTHONWARNINGS env var */
_Py_OptList env_warning_options;
- /* PYTHONPATH env var */
int argc;
wchar_t **argv;
} _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)
{
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")) {
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;
}
wchar_t *
-_Py_GetPathWithConfig(_PyMainInterpreterConfig *config)
+_Py_GetPathWithConfig(const _PyMainInterpreterConfig *config)
{
if (!module_search_path) {
calculate_path(config);
}
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) {
};
-PyMODINIT_FUNC
-_PyWarnings_Init(void)
+PyObject*
+_PyWarnings_InitWithConfig(const _PyCoreConfig *config)
{
PyObject *m;
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;
}
_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);
+}
}
/* Initialize _warnings. */
- _PyWarnings_Init();
+ if (_PyWarnings_InitWithConfig(&interp->core_config) == NULL) {
+ return _Py_INIT_ERR("can't initialize warnings");
+ }
/* This call sets up builtin and frozen import support */
if (!interp->core_config._disable_importlib) {
return err;
}
- if (config->install_signal_handlers) {
+ if (interp->config.install_signal_handlers) {
err = initsigs(); /* Signal handling stuff, including initintr() */
if (_Py_INIT_FAILED(err)) {
return err;
}
static wchar_t *default_home = NULL;
-static wchar_t env_home[MAXPATHLEN+1];
void
Py_SetPythonHome(wchar_t *home)
}
wchar_t *
-Py_GetPythonHome(void)
+_Py_GetPythonHomeWithConfig(const _PyMainInterpreterConfig *config)
{
- wchar_t *home = default_home;
- if (home == NULL && !Py_IgnoreEnvironmentFlag) {
- char* chome = Py_GETENV("PYTHONHOME");
- if (chome) {
- size_t size = Py_ARRAY_LENGTH(env_home);
- size_t r = mbstowcs(env_home, chome, size);
- if (r != (size_t)-1 && r < size)
- home = env_home;
- }
+ /* Use a static buffer to avoid heap memory allocation failure.
+ Py_GetPythonHome() doesn't allow to report error, and the caller
+ doesn't release memory. */
+ static wchar_t buffer[MAXPATHLEN+1];
+
+ if (default_home) {
+ return default_home;
+ }
+ if (config) {
+ return config->pythonhome;
}
- return home;
+
+ char *home = Py_GETENV("PYTHONHOME");
+ if (!home) {
+ return NULL;
+ }
+
+ size_t size = Py_ARRAY_LENGTH(buffer);
+ size_t r = mbstowcs(buffer, home, size);
+ if (r == (size_t)-1 || r >= size) {
+ /* conversion failed or the static buffer is too small */
+ return NULL;
+ }
+
+ return buffer;
+}
+
+wchar_t *
+Py_GetPythonHome(void)
+{
+ return _Py_GetPythonHomeWithConfig(NULL);
}
/* Add the __main__ module */