Skip to content

Commit

Permalink
bpo-32030: Add _PyMainInterpreterConfig_ReadEnv() (python#4542)
Browse files Browse the repository at this point in the history
Py_GetPath() and Py_Main() now call
_PyMainInterpreterConfig_ReadEnv() to share the same code to get
environment variables.

Changes:

* Add _PyMainInterpreterConfig_ReadEnv()
* Add _PyMainInterpreterConfig_Clear()
* Add _PyMem_RawWcsdup()
* _PyMainInterpreterConfig: rename pythonhome to home
* Rename _Py_ReadMainInterpreterConfig() to
  _PyMainInterpreterConfig_Read()
* Use _Py_INIT_USER_ERR(), instead of _Py_INIT_ERR(), for decoding
  errors: the user is able to fix the issue, it's not a bug in
  Python. Same change was made in _Py_INIT_NO_MEMORY().
* Remove _Py_GetPythonHomeWithConfig()
  • Loading branch information
vstinner authored Nov 24, 2017
1 parent 84c4b19 commit 46972b7
Show file tree
Hide file tree
Showing 8 changed files with 165 additions and 142 deletions.
13 changes: 6 additions & 7 deletions Include/pylifecycle.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ typedef struct {
Don't abort() the process on such error. */
#define _Py_INIT_USER_ERR(MSG) \
(_PyInitError){.prefix = _Py_INIT_GET_FUNC(), .msg = (MSG), .user_err = 1}
#define _Py_INIT_NO_MEMORY() _Py_INIT_ERR("memory allocation failed")
#define _Py_INIT_NO_MEMORY() _Py_INIT_USER_ERR("memory allocation failed")
#define _Py_INIT_FAILED(err) \
(err.msg != NULL)

Expand All @@ -42,11 +42,6 @@ PyAPI_FUNC(wchar_t *) Py_GetProgramName(void);

PyAPI_FUNC(void) Py_SetPythonHome(wchar_t *);
PyAPI_FUNC(wchar_t *) Py_GetPythonHome(void);
#ifdef Py_BUILD_CORE
PyAPI_FUNC(_PyInitError) _Py_GetPythonHomeWithConfig(
const _PyMainInterpreterConfig *config,
wchar_t **home);
#endif

#ifndef Py_LIMITED_API
/* Only used by applications that embed the interpreter and need to
Expand All @@ -58,7 +53,11 @@ PyAPI_FUNC(int) Py_SetStandardStreamEncoding(const char *encoding,
/* PEP 432 Multi-phase initialization API (Private while provisional!) */
PyAPI_FUNC(_PyInitError) _Py_InitializeCore(const _PyCoreConfig *);
PyAPI_FUNC(int) _Py_IsCoreInitialized(void);
PyAPI_FUNC(_PyInitError) _Py_ReadMainInterpreterConfig(_PyMainInterpreterConfig *);

PyAPI_FUNC(_PyInitError) _PyMainInterpreterConfig_Read(_PyMainInterpreterConfig *);
PyAPI_FUNC(_PyInitError) _PyMainInterpreterConfig_ReadEnv(_PyMainInterpreterConfig *);
PyAPI_FUNC(void) _PyMainInterpreterConfig_Clear(_PyMainInterpreterConfig *);

PyAPI_FUNC(_PyInitError) _Py_InitializeMainInterpreter(const _PyMainInterpreterConfig *);
#endif

Expand Down
6 changes: 6 additions & 0 deletions Include/pymem.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,8 +105,14 @@ PyAPI_FUNC(void *) PyMem_Realloc(void *ptr, size_t new_size);
PyAPI_FUNC(void) PyMem_Free(void *ptr);

#ifndef Py_LIMITED_API
/* strdup() using PyMem_RawMalloc() */
PyAPI_FUNC(char *) _PyMem_RawStrdup(const char *str);

/* strdup() using PyMem_Malloc() */
PyAPI_FUNC(char *) _PyMem_Strdup(const char *str);

/* wcsdup() using PyMem_RawMalloc() */
PyAPI_FUNC(wchar_t*) _PyMem_RawWcsdup(const wchar_t *str);
#endif

/* Macros. */
Expand Down
9 changes: 5 additions & 4 deletions Include/pystate.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,16 +60,17 @@ 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(). */
/* PYTHONPATH environment variable */
wchar_t *module_search_path_env;
/* PYTHONHOME environment variable, see also Py_SetPythonHome(). */
wchar_t *home;
} _PyMainInterpreterConfig;

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

typedef struct _is {

Expand Down
70 changes: 34 additions & 36 deletions Modules/getpath.c
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,6 @@ typedef struct {
wchar_t *path_env; /* PATH environment variable */
wchar_t *home; /* PYTHONHOME environment variable */
wchar_t *module_search_path_env; /* PYTHONPATH environment variable */
wchar_t *module_search_path_buffer;

wchar_t *prog; /* Program name */
wchar_t *pythonpath; /* PYTHONPATH define */
Expand Down Expand Up @@ -886,67 +885,45 @@ calculate_module_search_path(PyCalculatePath *calculate, PyPathConfig *config)
}


#define DECODE_FAILED(NAME, LEN) \
#define DECODE_LOCALE_ERR(NAME, LEN) \
((LEN) == (size_t)-2) \
? _Py_INIT_ERR("failed to decode " #NAME) \
? _Py_INIT_USER_ERR("failed to decode " #NAME) \
: _Py_INIT_NO_MEMORY()


static _PyInitError
calculate_init(PyCalculatePath *calculate,
const _PyMainInterpreterConfig *main_config)
{
_PyInitError err;

err = _Py_GetPythonHomeWithConfig(main_config, &calculate->home);
if (_Py_INIT_FAILED(err)) {
return err;
}
calculate->home = main_config->home;
calculate->module_search_path_env = main_config->module_search_path_env;

size_t len;
char *path = getenv("PATH");
if (path) {
calculate->path_env = Py_DecodeLocale(path, &len);
if (!calculate->path_env) {
return DECODE_FAILED("PATH environment variable", len);
return DECODE_LOCALE_ERR("PATH environment variable", len);
}
}

calculate->prog = Py_GetProgramName();

calculate->pythonpath = Py_DecodeLocale(PYTHONPATH, &len);
if (!calculate->pythonpath) {
return DECODE_FAILED("PYTHONPATH define", len);
return DECODE_LOCALE_ERR("PYTHONPATH define", len);
}
calculate->prefix = Py_DecodeLocale(PREFIX, &len);
if (!calculate->prefix) {
return DECODE_FAILED("PREFIX define", len);
return DECODE_LOCALE_ERR("PREFIX define", len);
}
calculate->exec_prefix = Py_DecodeLocale(EXEC_PREFIX, &len);
if (!calculate->prefix) {
return DECODE_FAILED("EXEC_PREFIX define", len);
return DECODE_LOCALE_ERR("EXEC_PREFIX define", len);
}
calculate->lib_python = Py_DecodeLocale("lib/python" VERSION, &len);
if (!calculate->lib_python) {
return DECODE_FAILED("EXEC_PREFIX define", len);
}

calculate->module_search_path_env = NULL;
if (main_config) {
if (main_config->module_search_path_env) {
calculate->module_search_path_env = main_config->module_search_path_env;
}

}
else {
char *pythonpath = Py_GETENV("PYTHONPATH");
if (pythonpath && pythonpath[0] != '\0') {
calculate->module_search_path_buffer = Py_DecodeLocale(pythonpath, &len);
if (!calculate->module_search_path_buffer) {
return DECODE_FAILED("PYTHONPATH environment variable", len);
}
calculate->module_search_path_env = calculate->module_search_path_buffer;
}
return DECODE_LOCALE_ERR("EXEC_PREFIX define", len);
}
return _Py_INIT_OK();
}
Expand All @@ -960,7 +937,6 @@ calculate_free(PyCalculatePath *calculate)
PyMem_RawFree(calculate->exec_prefix);
PyMem_RawFree(calculate->lib_python);
PyMem_RawFree(calculate->path_env);
PyMem_RawFree(calculate->module_search_path_buffer);
}


Expand Down Expand Up @@ -988,13 +964,24 @@ calculate_path_impl(PyCalculatePath *calculate, PyPathConfig *config)
static void
calculate_path(const _PyMainInterpreterConfig *main_config)
{
_PyInitError err;
PyCalculatePath calculate;
memset(&calculate, 0, sizeof(calculate));

_PyInitError err = calculate_init(&calculate, main_config);
_PyMainInterpreterConfig tmp_config;
int use_tmp = (main_config == NULL);
if (use_tmp) {
tmp_config = _PyMainInterpreterConfig_INIT;
err = _PyMainInterpreterConfig_ReadEnv(&tmp_config);
if (_Py_INIT_FAILED(err)) {
goto fatal_error;
}
main_config = &tmp_config;
}

err = calculate_init(&calculate, main_config);
if (_Py_INIT_FAILED(err)) {
calculate_free(&calculate);
_Py_FatalInitError(err);
goto fatal_error;
}

PyPathConfig new_path_config;
Expand All @@ -1003,7 +990,18 @@ calculate_path(const _PyMainInterpreterConfig *main_config)
calculate_path_impl(&calculate, &new_path_config);
path_config = new_path_config;

if (use_tmp) {
_PyMainInterpreterConfig_Clear(&tmp_config);
}
calculate_free(&calculate);
return;

fatal_error:
if (use_tmp) {
_PyMainInterpreterConfig_Clear(&tmp_config);
}
calculate_free(&calculate);
_Py_FatalInitError(err);
}


Expand Down
Loading

0 comments on commit 46972b7

Please sign in to comment.