Skip to content

Commit 46972b7

Browse files
authored
bpo-32030: Add _PyMainInterpreterConfig_ReadEnv() (#4542)
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()
1 parent 84c4b19 commit 46972b7

File tree

8 files changed

+165
-142
lines changed

8 files changed

+165
-142
lines changed

Include/pylifecycle.h

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ typedef struct {
3030
Don't abort() the process on such error. */
3131
#define _Py_INIT_USER_ERR(MSG) \
3232
(_PyInitError){.prefix = _Py_INIT_GET_FUNC(), .msg = (MSG), .user_err = 1}
33-
#define _Py_INIT_NO_MEMORY() _Py_INIT_ERR("memory allocation failed")
33+
#define _Py_INIT_NO_MEMORY() _Py_INIT_USER_ERR("memory allocation failed")
3434
#define _Py_INIT_FAILED(err) \
3535
(err.msg != NULL)
3636

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

4343
PyAPI_FUNC(void) Py_SetPythonHome(wchar_t *);
4444
PyAPI_FUNC(wchar_t *) Py_GetPythonHome(void);
45-
#ifdef Py_BUILD_CORE
46-
PyAPI_FUNC(_PyInitError) _Py_GetPythonHomeWithConfig(
47-
const _PyMainInterpreterConfig *config,
48-
wchar_t **home);
49-
#endif
5045

5146
#ifndef Py_LIMITED_API
5247
/* Only used by applications that embed the interpreter and need to
@@ -58,7 +53,11 @@ PyAPI_FUNC(int) Py_SetStandardStreamEncoding(const char *encoding,
5853
/* PEP 432 Multi-phase initialization API (Private while provisional!) */
5954
PyAPI_FUNC(_PyInitError) _Py_InitializeCore(const _PyCoreConfig *);
6055
PyAPI_FUNC(int) _Py_IsCoreInitialized(void);
61-
PyAPI_FUNC(_PyInitError) _Py_ReadMainInterpreterConfig(_PyMainInterpreterConfig *);
56+
57+
PyAPI_FUNC(_PyInitError) _PyMainInterpreterConfig_Read(_PyMainInterpreterConfig *);
58+
PyAPI_FUNC(_PyInitError) _PyMainInterpreterConfig_ReadEnv(_PyMainInterpreterConfig *);
59+
PyAPI_FUNC(void) _PyMainInterpreterConfig_Clear(_PyMainInterpreterConfig *);
60+
6261
PyAPI_FUNC(_PyInitError) _Py_InitializeMainInterpreter(const _PyMainInterpreterConfig *);
6362
#endif
6463

Include/pymem.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,8 +105,14 @@ PyAPI_FUNC(void *) PyMem_Realloc(void *ptr, size_t new_size);
105105
PyAPI_FUNC(void) PyMem_Free(void *ptr);
106106

107107
#ifndef Py_LIMITED_API
108+
/* strdup() using PyMem_RawMalloc() */
108109
PyAPI_FUNC(char *) _PyMem_RawStrdup(const char *str);
110+
111+
/* strdup() using PyMem_Malloc() */
109112
PyAPI_FUNC(char *) _PyMem_Strdup(const char *str);
113+
114+
/* wcsdup() using PyMem_RawMalloc() */
115+
PyAPI_FUNC(wchar_t*) _PyMem_RawWcsdup(const wchar_t *str);
110116
#endif
111117

112118
/* Macros. */

Include/pystate.h

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -60,16 +60,17 @@ typedef struct {
6060
*/
6161
typedef struct {
6262
int install_signal_handlers;
63-
wchar_t *module_search_path_env; /* PYTHONPATH environment variable */
64-
wchar_t *pythonhome; /* PYTHONHOME environment variable,
65-
see also Py_SetPythonHome(). */
63+
/* PYTHONPATH environment variable */
64+
wchar_t *module_search_path_env;
65+
/* PYTHONHOME environment variable, see also Py_SetPythonHome(). */
66+
wchar_t *home;
6667
} _PyMainInterpreterConfig;
6768

6869
#define _PyMainInterpreterConfig_INIT \
6970
(_PyMainInterpreterConfig){\
7071
.install_signal_handlers = -1, \
7172
.module_search_path_env = NULL, \
72-
.pythonhome = NULL}
73+
.home = NULL}
7374

7475
typedef struct _is {
7576

Modules/getpath.c

Lines changed: 34 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,6 @@ typedef struct {
120120
wchar_t *path_env; /* PATH environment variable */
121121
wchar_t *home; /* PYTHONHOME environment variable */
122122
wchar_t *module_search_path_env; /* PYTHONPATH environment variable */
123-
wchar_t *module_search_path_buffer;
124123

125124
wchar_t *prog; /* Program name */
126125
wchar_t *pythonpath; /* PYTHONPATH define */
@@ -886,67 +885,45 @@ calculate_module_search_path(PyCalculatePath *calculate, PyPathConfig *config)
886885
}
887886

888887

889-
#define DECODE_FAILED(NAME, LEN) \
888+
#define DECODE_LOCALE_ERR(NAME, LEN) \
890889
((LEN) == (size_t)-2) \
891-
? _Py_INIT_ERR("failed to decode " #NAME) \
890+
? _Py_INIT_USER_ERR("failed to decode " #NAME) \
892891
: _Py_INIT_NO_MEMORY()
893892

894893

895894
static _PyInitError
896895
calculate_init(PyCalculatePath *calculate,
897896
const _PyMainInterpreterConfig *main_config)
898897
{
899-
_PyInitError err;
900-
901-
err = _Py_GetPythonHomeWithConfig(main_config, &calculate->home);
902-
if (_Py_INIT_FAILED(err)) {
903-
return err;
904-
}
898+
calculate->home = main_config->home;
899+
calculate->module_search_path_env = main_config->module_search_path_env;
905900

906901
size_t len;
907902
char *path = getenv("PATH");
908903
if (path) {
909904
calculate->path_env = Py_DecodeLocale(path, &len);
910905
if (!calculate->path_env) {
911-
return DECODE_FAILED("PATH environment variable", len);
906+
return DECODE_LOCALE_ERR("PATH environment variable", len);
912907
}
913908
}
914909

915910
calculate->prog = Py_GetProgramName();
916911

917912
calculate->pythonpath = Py_DecodeLocale(PYTHONPATH, &len);
918913
if (!calculate->pythonpath) {
919-
return DECODE_FAILED("PYTHONPATH define", len);
914+
return DECODE_LOCALE_ERR("PYTHONPATH define", len);
920915
}
921916
calculate->prefix = Py_DecodeLocale(PREFIX, &len);
922917
if (!calculate->prefix) {
923-
return DECODE_FAILED("PREFIX define", len);
918+
return DECODE_LOCALE_ERR("PREFIX define", len);
924919
}
925920
calculate->exec_prefix = Py_DecodeLocale(EXEC_PREFIX, &len);
926921
if (!calculate->prefix) {
927-
return DECODE_FAILED("EXEC_PREFIX define", len);
922+
return DECODE_LOCALE_ERR("EXEC_PREFIX define", len);
928923
}
929924
calculate->lib_python = Py_DecodeLocale("lib/python" VERSION, &len);
930925
if (!calculate->lib_python) {
931-
return DECODE_FAILED("EXEC_PREFIX define", len);
932-
}
933-
934-
calculate->module_search_path_env = NULL;
935-
if (main_config) {
936-
if (main_config->module_search_path_env) {
937-
calculate->module_search_path_env = main_config->module_search_path_env;
938-
}
939-
940-
}
941-
else {
942-
char *pythonpath = Py_GETENV("PYTHONPATH");
943-
if (pythonpath && pythonpath[0] != '\0') {
944-
calculate->module_search_path_buffer = Py_DecodeLocale(pythonpath, &len);
945-
if (!calculate->module_search_path_buffer) {
946-
return DECODE_FAILED("PYTHONPATH environment variable", len);
947-
}
948-
calculate->module_search_path_env = calculate->module_search_path_buffer;
949-
}
926+
return DECODE_LOCALE_ERR("EXEC_PREFIX define", len);
950927
}
951928
return _Py_INIT_OK();
952929
}
@@ -960,7 +937,6 @@ calculate_free(PyCalculatePath *calculate)
960937
PyMem_RawFree(calculate->exec_prefix);
961938
PyMem_RawFree(calculate->lib_python);
962939
PyMem_RawFree(calculate->path_env);
963-
PyMem_RawFree(calculate->module_search_path_buffer);
964940
}
965941

966942

@@ -988,13 +964,24 @@ calculate_path_impl(PyCalculatePath *calculate, PyPathConfig *config)
988964
static void
989965
calculate_path(const _PyMainInterpreterConfig *main_config)
990966
{
967+
_PyInitError err;
991968
PyCalculatePath calculate;
992969
memset(&calculate, 0, sizeof(calculate));
993970

994-
_PyInitError err = calculate_init(&calculate, main_config);
971+
_PyMainInterpreterConfig tmp_config;
972+
int use_tmp = (main_config == NULL);
973+
if (use_tmp) {
974+
tmp_config = _PyMainInterpreterConfig_INIT;
975+
err = _PyMainInterpreterConfig_ReadEnv(&tmp_config);
976+
if (_Py_INIT_FAILED(err)) {
977+
goto fatal_error;
978+
}
979+
main_config = &tmp_config;
980+
}
981+
982+
err = calculate_init(&calculate, main_config);
995983
if (_Py_INIT_FAILED(err)) {
996-
calculate_free(&calculate);
997-
_Py_FatalInitError(err);
984+
goto fatal_error;
998985
}
999986

1000987
PyPathConfig new_path_config;
@@ -1003,7 +990,18 @@ calculate_path(const _PyMainInterpreterConfig *main_config)
1003990
calculate_path_impl(&calculate, &new_path_config);
1004991
path_config = new_path_config;
1005992

993+
if (use_tmp) {
994+
_PyMainInterpreterConfig_Clear(&tmp_config);
995+
}
996+
calculate_free(&calculate);
997+
return;
998+
999+
fatal_error:
1000+
if (use_tmp) {
1001+
_PyMainInterpreterConfig_Clear(&tmp_config);
1002+
}
10061003
calculate_free(&calculate);
1004+
_Py_FatalInitError(err);
10071005
}
10081006

10091007

0 commit comments

Comments
 (0)