Commit 9cfc0026 authored by Victor Stinner's avatar Victor Stinner Committed by GitHub

bpo-32030: Complete _PyCoreConfig_Read() (#4946)

* Add _PyCoreConfig.install_signal_handlers
* Remove _PyMain.config: _PyMainInterpreterConfig usage is now
  restricted to pymain_init_python_main().
* Rename _PyMain.core_config to _PyMain.config
* _PyMainInterpreterConfig_Read() now creates the xoptions dictionary
   from the core config
* Fix _PyMainInterpreterConfig_Read(): don't replace xoptions and
  argv if they are already set.
parent 51eb1c6b
...@@ -25,6 +25,7 @@ typedef PyObject* (*_PyFrameEvalFunction)(struct _frame *, int); ...@@ -25,6 +25,7 @@ typedef PyObject* (*_PyFrameEvalFunction)(struct _frame *, int);
typedef struct { typedef struct {
int install_signal_handlers; /* Install signal handlers? -1 means unset */
int ignore_environment; /* -E */ int ignore_environment; /* -E */
int use_hash_seed; /* PYTHONHASHSEED=x */ int use_hash_seed; /* PYTHONHASHSEED=x */
unsigned long hash_seed; unsigned long hash_seed;
...@@ -62,6 +63,7 @@ typedef struct { ...@@ -62,6 +63,7 @@ typedef struct {
#define _PyCoreConfig_INIT \ #define _PyCoreConfig_INIT \
(_PyCoreConfig){ \ (_PyCoreConfig){ \
.install_signal_handlers = -1, \
.use_hash_seed = -1, \ .use_hash_seed = -1, \
.coerce_c_locale = -1, \ .coerce_c_locale = -1, \
.utf8_mode = -1, \ .utf8_mode = -1, \
...@@ -73,7 +75,7 @@ typedef struct { ...@@ -73,7 +75,7 @@ typedef struct {
* See PEP 432 for final anticipated contents * See PEP 432 for final anticipated contents
*/ */
typedef struct { typedef struct {
int install_signal_handlers; int install_signal_handlers; /* Install signal handlers? -1 means unset */
PyObject *argv; /* sys.argv list, can be NULL */ PyObject *argv; /* sys.argv list, can be NULL */
PyObject *executable; /* sys.executable str */ PyObject *executable; /* sys.executable str */
PyObject *prefix; /* sys.prefix str */ PyObject *prefix; /* sys.prefix str */
......
...@@ -164,7 +164,7 @@ pymain_usage(int error, const wchar_t* program) ...@@ -164,7 +164,7 @@ pymain_usage(int error, const wchar_t* program)
static const char* static const char*
pymain_get_env_var(const char *name) config_get_env_var(const char *name)
{ {
const char *var = Py_GETENV(name); const char *var = Py_GETENV(name);
if (var && var[0] != '\0') { if (var && var[0] != '\0') {
...@@ -223,7 +223,7 @@ config_get_env_var_dup(wchar_t **dest, wchar_t *wname, char *name) ...@@ -223,7 +223,7 @@ config_get_env_var_dup(wchar_t **dest, wchar_t *wname, char *name)
static void static void
pymain_run_startup(PyCompilerFlags *cf) pymain_run_startup(PyCompilerFlags *cf)
{ {
const char *startup = pymain_get_env_var("PYTHONSTARTUP"); const char *startup = config_get_env_var("PYTHONSTARTUP");
if (startup == NULL) { if (startup == NULL) {
return; return;
} }
...@@ -477,15 +477,13 @@ typedef struct { ...@@ -477,15 +477,13 @@ typedef struct {
wchar_t *command; /* -c argument */ wchar_t *command; /* -c argument */
wchar_t *module; /* -m argument */ wchar_t *module; /* -m argument */
_PyCoreConfig core_config; _PyCoreConfig config;
_PyMainInterpreterConfig config;
PyObject *main_importer_path; PyObject *main_importer_path;
} _PyMain; } _PyMain;
#define _PyMain_INIT \ #define _PyMain_INIT \
{.core_config = _PyCoreConfig_INIT, \ {.config = _PyCoreConfig_INIT, \
.config = _PyMainInterpreterConfig_INIT, \
.err = _Py_INIT_OK()} .err = _Py_INIT_OK()}
/* Note: _PyMain_INIT sets other fields to 0/NULL */ /* Note: _PyMain_INIT sets other fields to 0/NULL */
...@@ -559,8 +557,8 @@ pymain_init_cmdline_argv(_PyMain *pymain, _Py_CommandLineDetails *cmdline) ...@@ -559,8 +557,8 @@ pymain_init_cmdline_argv(_PyMain *pymain, _Py_CommandLineDetails *cmdline)
else { else {
program = L""; program = L"";
} }
pymain->core_config.program = pymain_wstrdup(pymain, program); pymain->config.program = pymain_wstrdup(pymain, program);
if (pymain->core_config.program == NULL) { if (pymain->config.program == NULL) {
return -1; return -1;
} }
...@@ -607,16 +605,14 @@ pymain_clear_pymain(_PyMain *pymain) ...@@ -607,16 +605,14 @@ pymain_clear_pymain(_PyMain *pymain)
} }
static void static void
pymain_clear_configs(_PyMain *pymain) pymain_clear_config(_PyMain *pymain)
{ {
_PyMainInterpreterConfig_Clear(&pymain->config);
/* Clear core config with the memory allocator /* Clear core config with the memory allocator
used by pymain_read_conf() */ used by pymain_read_conf() */
PyMemAllocatorEx old_alloc; PyMemAllocatorEx old_alloc;
_PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc); _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
_PyCoreConfig_Clear(&pymain->core_config); _PyCoreConfig_Clear(&pymain->config);
PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
} }
...@@ -626,7 +622,6 @@ static void ...@@ -626,7 +622,6 @@ static void
pymain_free_python(_PyMain *pymain) pymain_free_python(_PyMain *pymain)
{ {
Py_CLEAR(pymain->main_importer_path); Py_CLEAR(pymain->main_importer_path);
_PyMainInterpreterConfig_Clear(&pymain->config);
#ifdef __INSURE__ #ifdef __INSURE__
/* Insure++ is a memory analysis tool that aids in discovering /* Insure++ is a memory analysis tool that aids in discovering
...@@ -658,7 +653,7 @@ pymain_free_raw(_PyMain *pymain) ...@@ -658,7 +653,7 @@ pymain_free_raw(_PyMain *pymain)
PyMemAllocatorEx old_alloc; PyMemAllocatorEx old_alloc;
_PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc); _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
_PyCoreConfig_Clear(&pymain->core_config); _PyCoreConfig_Clear(&pymain->config);
pymain_clear_pymain(pymain); pymain_clear_pymain(pymain);
clear_wstrlist(orig_argc, orig_argv); clear_wstrlist(orig_argc, orig_argv);
...@@ -702,24 +697,35 @@ error: ...@@ -702,24 +697,35 @@ error:
} }
static int static _PyInitError
pymain_wstrlist_append(_PyMain *pymain, int *len, wchar_t ***list, const wchar_t *str) wstrlist_append(int *len, wchar_t ***list, const wchar_t *str)
{ {
wchar_t *str2 = pymain_wstrdup(pymain, str); wchar_t *str2 = _PyMem_RawWcsdup(str);
if (str2 == NULL) { if (str2 == NULL) {
return -1; return _Py_INIT_NO_MEMORY();
} }
size_t size = (*len + 1) * sizeof(list[0]); size_t size = (*len + 1) * sizeof(list[0]);
wchar_t **list2 = (wchar_t **)PyMem_RawRealloc(*list, size); wchar_t **list2 = (wchar_t **)PyMem_RawRealloc(*list, size);
if (list2 == NULL) { if (list2 == NULL) {
PyMem_RawFree(str2); PyMem_RawFree(str2);
pymain->err = _Py_INIT_NO_MEMORY(); return _Py_INIT_NO_MEMORY();
return -1;
} }
list2[*len] = str2; list2[*len] = str2;
*list = list2; *list = list2;
(*len)++; (*len)++;
return _Py_INIT_OK();
}
static int
pymain_wstrlist_append(_PyMain *pymain, int *len, wchar_t ***list, const wchar_t *str)
{
_PyInitError err = wstrlist_append(len, list, str);
if (_Py_INIT_FAILED(err)) {
pymain->err = err;
return -1;
}
return 0; return 0;
} }
...@@ -731,6 +737,8 @@ pymain_wstrlist_append(_PyMain *pymain, int *len, wchar_t ***list, const wchar_t ...@@ -731,6 +737,8 @@ pymain_wstrlist_append(_PyMain *pymain, int *len, wchar_t ***list, const wchar_t
static int static int
pymain_parse_cmdline_impl(_PyMain *pymain, _Py_CommandLineDetails *cmdline) pymain_parse_cmdline_impl(_PyMain *pymain, _Py_CommandLineDetails *cmdline)
{ {
_PyCoreConfig *config = &pymain->config;
_PyOS_ResetGetOpt(); _PyOS_ResetGetOpt();
do { do {
int longindex = -1; int longindex = -1;
...@@ -799,7 +807,7 @@ pymain_parse_cmdline_impl(_PyMain *pymain, _Py_CommandLineDetails *cmdline) ...@@ -799,7 +807,7 @@ pymain_parse_cmdline_impl(_PyMain *pymain, _Py_CommandLineDetails *cmdline)
break; break;
case 'I': case 'I':
pymain->core_config.ignore_environment++; config->ignore_environment++;
cmdline->isolated++; cmdline->isolated++;
cmdline->no_user_site_directory++; cmdline->no_user_site_directory++;
break; break;
...@@ -823,7 +831,7 @@ pymain_parse_cmdline_impl(_PyMain *pymain, _Py_CommandLineDetails *cmdline) ...@@ -823,7 +831,7 @@ pymain_parse_cmdline_impl(_PyMain *pymain, _Py_CommandLineDetails *cmdline)
break; break;
case 'E': case 'E':
pymain->core_config.ignore_environment++; config->ignore_environment++;
break; break;
case 't': case 't':
...@@ -862,8 +870,8 @@ pymain_parse_cmdline_impl(_PyMain *pymain, _Py_CommandLineDetails *cmdline) ...@@ -862,8 +870,8 @@ pymain_parse_cmdline_impl(_PyMain *pymain, _Py_CommandLineDetails *cmdline)
case 'X': case 'X':
if (pymain_wstrlist_append(pymain, if (pymain_wstrlist_append(pymain,
&pymain->core_config.nxoption, &config->nxoption,
&pymain->core_config.xoptions, &config->xoptions,
_PyOS_optarg) < 0) { _PyOS_optarg) < 0) {
return -1; return -1;
} }
...@@ -874,7 +882,7 @@ pymain_parse_cmdline_impl(_PyMain *pymain, _Py_CommandLineDetails *cmdline) ...@@ -874,7 +882,7 @@ pymain_parse_cmdline_impl(_PyMain *pymain, _Py_CommandLineDetails *cmdline)
break; break;
case 'R': case 'R':
pymain->core_config.use_hash_seed = 0; config->use_hash_seed = 0;
break; break;
/* This space reserved for other options */ /* This space reserved for other options */
...@@ -903,7 +911,7 @@ pymain_parse_cmdline_impl(_PyMain *pymain, _Py_CommandLineDetails *cmdline) ...@@ -903,7 +911,7 @@ pymain_parse_cmdline_impl(_PyMain *pymain, _Py_CommandLineDetails *cmdline)
static int static int
pymain_add_xoption(PyObject *opts, const wchar_t *s) add_xoption(PyObject *opts, const wchar_t *s)
{ {
PyObject *name, *value; PyObject *name, *value;
...@@ -933,48 +941,51 @@ error: ...@@ -933,48 +941,51 @@ error:
return -1; return -1;
} }
static int
pymain_init_xoptions_dict(_PyMain *pymain) static PyObject*
config_create_xoptions_dict(const _PyCoreConfig *config)
{ {
int nxoption = pymain->core_config.nxoption; int nxoption = config->nxoption;
wchar_t **xoptions = pymain->core_config.xoptions; wchar_t **xoptions = config->xoptions;
PyObject *dict = PyDict_New(); PyObject *dict = PyDict_New();
if (dict == NULL) { if (dict == NULL) {
return -1; return NULL;
} }
for (int i=0; i < nxoption; i++) { for (int i=0; i < nxoption; i++) {
wchar_t *option = xoptions[i]; wchar_t *option = xoptions[i];
if (pymain_add_xoption(dict, option) < 0) { if (add_xoption(dict, option) < 0) {
Py_DECREF(dict); Py_DECREF(dict);
return -1; return NULL;
} }
} }
pymain->config.xoptions = dict; return dict;
return 0;
} }
static int static _PyInitError
pymain_add_warnings_optlist(_PyMain *pymain, int len, wchar_t **options) config_add_warnings_optlist(_PyCoreConfig *config, int len, wchar_t **options)
{ {
for (int i = 0; i < len; i++) { for (int i = 0; i < len; i++) {
if (pymain_wstrlist_append(pymain, _PyInitError err = wstrlist_append(&config->nwarnoption,
&pymain->core_config.nwarnoption, &config->warnoptions,
&pymain->core_config.warnoptions, options[i]);
options[i]) < 0) if (_Py_INIT_FAILED(err)) {
{ return err;
return -1;
} }
} }
return 0; return _Py_INIT_OK();
} }
static int static _PyInitError
pymain_init_warnoptions(_PyMain *pymain, _Py_CommandLineDetails *cmdline) config_init_warnoptions(_PyCoreConfig *config, _Py_CommandLineDetails *cmdline)
{ {
_PyInitError err;
assert(config->nwarnoption == 0);
/* The priority order for warnings configuration is (highest precedence /* The priority order for warnings configuration is (highest precedence
* first): * first):
* *
...@@ -990,22 +1001,27 @@ pymain_init_warnoptions(_PyMain *pymain, _Py_CommandLineDetails *cmdline) ...@@ -990,22 +1001,27 @@ pymain_init_warnoptions(_PyMain *pymain, _Py_CommandLineDetails *cmdline)
* the lowest precedence entries first so that later entries override them. * the lowest precedence entries first so that later entries override them.
*/ */
if (pymain->core_config.dev_mode) { if (config->dev_mode) {
if (pymain_wstrlist_append(pymain, err = wstrlist_append(&config->nwarnoption,
&pymain->core_config.nwarnoption, &config->warnoptions,
&pymain->core_config.warnoptions, L"default");
L"default") < 0) if (_Py_INIT_FAILED(err)) {
{ return err;
return -1;
} }
} }
if (pymain_add_warnings_optlist(pymain, cmdline->nenv_warnoption, cmdline->env_warnoptions) < 0) { err = config_add_warnings_optlist(config,
return -1; cmdline->nenv_warnoption,
cmdline->env_warnoptions);
if (_Py_INIT_FAILED(err)) {
return err;
} }
if (pymain_add_warnings_optlist(pymain, cmdline->nwarnoption, cmdline->warnoptions) < 0) { err = config_add_warnings_optlist(config,
return -1; cmdline->nwarnoption,
cmdline->warnoptions);
if (_Py_INIT_FAILED(err)) {
return err;
} }
/* If the bytes_warning_flag isn't set, bytesobject.c and bytearrayobject.c /* If the bytes_warning_flag isn't set, bytesobject.c and bytearrayobject.c
...@@ -1020,29 +1036,28 @@ pymain_init_warnoptions(_PyMain *pymain, _Py_CommandLineDetails *cmdline) ...@@ -1020,29 +1036,28 @@ pymain_init_warnoptions(_PyMain *pymain, _Py_CommandLineDetails *cmdline)
else { else {
filter = L"default::BytesWarning"; filter = L"default::BytesWarning";
} }
if (pymain_wstrlist_append(pymain, err = wstrlist_append(&config->nwarnoption,
&pymain->core_config.nwarnoption, &config->warnoptions,
&pymain->core_config.warnoptions, filter);
filter) < 0) if (_Py_INIT_FAILED(err)) {
{ return err;
return -1;
} }
} }
return 0; return _Py_INIT_OK();
} }
static int static int
config_init_warnoptions(_PyMainInterpreterConfig *config, main_config_init_warnoptions(_PyMainInterpreterConfig *main_config,
const _PyCoreConfig *core_config) const _PyCoreConfig *config)
{ {
PyObject *warnoptions = PyList_New(0); PyObject *warnoptions = PyList_New(0);
if (warnoptions == NULL) { if (warnoptions == NULL) {
return -1; return -1;
} }
for (int i = 0; i < core_config->nwarnoption; i++) { for (int i = 0; i < config->nwarnoption; i++) {
PyObject *option = PyUnicode_FromWideChar(core_config->warnoptions[i], -1); PyObject *option = PyUnicode_FromWideChar(config->warnoptions[i], -1);
if (option == NULL) { if (option == NULL) {
goto error; goto error;
} }
...@@ -1053,7 +1068,7 @@ config_init_warnoptions(_PyMainInterpreterConfig *config, ...@@ -1053,7 +1068,7 @@ config_init_warnoptions(_PyMainInterpreterConfig *config,
Py_DECREF(option); Py_DECREF(option);
} }
config->warnoptions = warnoptions; main_config->warnoptions = warnoptions;
return 0; return 0;
error: error:
...@@ -1065,22 +1080,21 @@ error: ...@@ -1065,22 +1080,21 @@ error:
/* Get warning options from PYTHONWARNINGS environment variable. /* Get warning options from PYTHONWARNINGS environment variable.
Return 0 on success. Return 0 on success.
Set pymain->err and return -1 on error. */ Set pymain->err and return -1 on error. */
static int static _PyInitError
pymain_warnings_envvar(_PyMain *pymain, _Py_CommandLineDetails *cmdline) cmdline_init_env_warnoptions(_Py_CommandLineDetails *cmdline)
{ {
if (Py_IgnoreEnvironmentFlag) { if (Py_IgnoreEnvironmentFlag) {
return 0; return _Py_INIT_OK();
} }
wchar_t *env; wchar_t *env;
int res = config_get_env_var_dup(&env, L"PYTHONWARNINGS", "PYTHONWARNINGS"); int res = config_get_env_var_dup(&env, L"PYTHONWARNINGS", "PYTHONWARNINGS");
if (res < 0) { if (res < 0) {
pymain->err = DECODE_LOCALE_ERR("PYTHONWARNINGS", res); return DECODE_LOCALE_ERR("PYTHONWARNINGS", res);
return -1;
} }
if (env == NULL) { if (env == NULL) {
return 0; return _Py_INIT_OK();
} }
...@@ -1089,17 +1103,16 @@ pymain_warnings_envvar(_PyMain *pymain, _Py_CommandLineDetails *cmdline) ...@@ -1089,17 +1103,16 @@ pymain_warnings_envvar(_PyMain *pymain, _Py_CommandLineDetails *cmdline)
warning != NULL; warning != NULL;
warning = WCSTOK(NULL, L",", &context)) warning = WCSTOK(NULL, L",", &context))
{ {
if (pymain_wstrlist_append(pymain, _PyInitError err = wstrlist_append(&cmdline->nenv_warnoption,
&cmdline->nenv_warnoption, &cmdline->env_warnoptions,
&cmdline->env_warnoptions, warning);
warning) < 0) if (_Py_INIT_FAILED(err)) {
{
PyMem_RawFree(env); PyMem_RawFree(env);
return -1; return err;
} }
} }
PyMem_RawFree(env); PyMem_RawFree(env);
return 0; return _Py_INIT_OK();
} }
...@@ -1170,7 +1183,7 @@ config_init_program_name(_PyCoreConfig *config) ...@@ -1170,7 +1183,7 @@ config_init_program_name(_PyCoreConfig *config)
so the actual executable path is passed in an environment variable. so the actual executable path is passed in an environment variable.
See Lib/plat-mac/bundlebuiler.py for details about the bootstrap See Lib/plat-mac/bundlebuiler.py for details about the bootstrap
script. */ script. */
const char *p = pymain_get_env_var("PYTHONEXECUTABLE"); const char *p = config_get_env_var("PYTHONEXECUTABLE");
if (p != NULL) { if (p != NULL) {
size_t len; size_t len;
wchar_t* program_name = Py_DecodeLocale(p, &len); wchar_t* program_name = Py_DecodeLocale(p, &len);
...@@ -1304,23 +1317,22 @@ pymain_init_core_argv(_PyMain *pymain, _Py_CommandLineDetails *cmdline) ...@@ -1304,23 +1317,22 @@ pymain_init_core_argv(_PyMain *pymain, _Py_CommandLineDetails *cmdline)
argv[0] = arg0; argv[0] = arg0;
} }
pymain->core_config.argc = argc; pymain->config.argc = argc;
pymain->core_config.argv = argv; pymain->config.argv = argv;
return 0; return 0;
} }
static int static int
config_init_argv(_PyMainInterpreterConfig *config, const _PyCoreConfig *core_config) main_config_init_argv(_PyMainInterpreterConfig *main_config,
const _PyCoreConfig *config)
{ {
assert(config->argv == NULL); if (config->argc < 0) {
if (core_config->argc < 0) {
return 0; return 0;
} }
int argc = core_config->argc; int argc = config->argc;
wchar_t** argv = core_config->argv; wchar_t** argv = config->argv;
assert(argc >= 1 && argv != NULL); assert(argc >= 1 && argv != NULL);
PyObject *list = PyList_New(argc); PyObject *list = PyList_New(argc);
...@@ -1337,13 +1349,13 @@ config_init_argv(_PyMainInterpreterConfig *config, const _PyCoreConfig *core_con ...@@ -1337,13 +1349,13 @@ config_init_argv(_PyMainInterpreterConfig *config, const _PyCoreConfig *core_con
PyList_SET_ITEM(list, i, v); PyList_SET_ITEM(list, i, v);
} }
config->argv = list; main_config->argv = list;
return 0; return 0;
} }
static int static int
pymain_init_path0(_PyMain *pymain, PyObject **path0) pymain_compute_path0(_PyMain *pymain, PyObject **path0)
{ {
if (pymain->main_importer_path != NULL) { if (pymain->main_importer_path != NULL) {
/* Let pymain_run_main_from_importer() adjust sys.path[0] later */ /* Let pymain_run_main_from_importer() adjust sys.path[0] later */
...@@ -1356,8 +1368,8 @@ pymain_init_path0(_PyMain *pymain, PyObject **path0) ...@@ -1356,8 +1368,8 @@ pymain_init_path0(_PyMain *pymain, PyObject **path0)
return 0; return 0;
} }
*path0 = _PyPathConfig_ComputeArgv0(pymain->core_config.argc, *path0 = _PyPathConfig_ComputeArgv0(pymain->config.argc,
pymain->core_config.argv); pymain->config.argv);
if (*path0 == NULL) { if (*path0 == NULL) {
pymain->err = _Py_INIT_NO_MEMORY(); pymain->err = _Py_INIT_NO_MEMORY();
return -1; return -1;
...@@ -1408,8 +1420,8 @@ pymain_get_global_config(_PyMain *pymain, _Py_CommandLineDetails *cmdline) ...@@ -1408,8 +1420,8 @@ pymain_get_global_config(_PyMain *pymain, _Py_CommandLineDetails *cmdline)
#endif #endif
cmdline->check_hash_pycs_mode = _Py_CheckHashBasedPycsMode ; cmdline->check_hash_pycs_mode = _Py_CheckHashBasedPycsMode ;
pymain->core_config.ignore_environment = Py_IgnoreEnvironmentFlag; pymain->config.ignore_environment = Py_IgnoreEnvironmentFlag;
pymain->core_config.utf8_mode = Py_UTF8Mode; pymain->config.utf8_mode = Py_UTF8Mode;
} }
...@@ -1435,12 +1447,12 @@ pymain_set_global_config(_PyMain *pymain, _Py_CommandLineDetails *cmdline) ...@@ -1435,12 +1447,12 @@ pymain_set_global_config(_PyMain *pymain, _Py_CommandLineDetails *cmdline)
Py_LegacyWindowsStdioFlag = cmdline->legacy_windows_stdio; Py_LegacyWindowsStdioFlag = cmdline->legacy_windows_stdio;
#endif #endif
Py_IgnoreEnvironmentFlag = pymain->core_config.ignore_environment; Py_IgnoreEnvironmentFlag = pymain->config.ignore_environment;
Py_UTF8Mode = pymain->core_config.utf8_mode; Py_UTF8Mode = pymain->config.utf8_mode;
/* Random or non-zero hash seed */ /* Random or non-zero hash seed */
Py_HashRandomizationFlag = (pymain->core_config.use_hash_seed == 0 || Py_HashRandomizationFlag = (pymain->config.use_hash_seed == 0 ||
pymain->core_config.hash_seed != 0); pymain->config.hash_seed != 0);
} }
...@@ -1483,7 +1495,7 @@ pymain_open_filename(_PyMain *pymain) ...@@ -1483,7 +1495,7 @@ pymain_open_filename(_PyMain *pymain)
else else
cfilename = "<unprintable file name>"; cfilename = "<unprintable file name>";
fprintf(stderr, "%ls: can't open file '%s': [Errno %d] %s\n", fprintf(stderr, "%ls: can't open file '%s': [Errno %d] %s\n",
pymain->core_config.program, cfilename, err, strerror(err)); pymain->config.program, cfilename, err, strerror(err));
PyMem_Free(cfilename_buffer); PyMem_Free(cfilename_buffer);
pymain->status = 2; pymain->status = 2;
return NULL; return NULL;
...@@ -1506,7 +1518,7 @@ pymain_open_filename(_PyMain *pymain) ...@@ -1506,7 +1518,7 @@ pymain_open_filename(_PyMain *pymain)
S_ISDIR(sb.st_mode)) { S_ISDIR(sb.st_mode)) {
fprintf(stderr, fprintf(stderr,
"%ls: '%ls' is a directory, cannot continue\n", "%ls: '%ls' is a directory, cannot continue\n",
pymain->core_config.program, pymain->filename); pymain->config.program, pymain->filename);
fclose(fp); fclose(fp);
pymain->status = 1; pymain->status = 1;
return NULL; return NULL;
...@@ -1550,7 +1562,7 @@ pymain_repl(_PyMain *pymain, PyCompilerFlags *cf) ...@@ -1550,7 +1562,7 @@ pymain_repl(_PyMain *pymain, PyCompilerFlags *cf)
{ {
/* Check this environment variable at the end, to give programs the /* Check this environment variable at the end, to give programs the
opportunity to set it from Python. */ opportunity to set it from Python. */
if (!Py_InspectFlag && pymain_get_env_var("PYTHONINSPECT")) { if (!Py_InspectFlag && config_get_env_var("PYTHONINSPECT")) {
Py_InspectFlag = 1; Py_InspectFlag = 1;
} }
...@@ -1580,7 +1592,7 @@ pymain_parse_cmdline(_PyMain *pymain, _Py_CommandLineDetails *cmdline) ...@@ -1580,7 +1592,7 @@ pymain_parse_cmdline(_PyMain *pymain, _Py_CommandLineDetails *cmdline)
return -1; return -1;
} }
if (res) { if (res) {
pymain_usage(1, pymain->core_config.program); pymain_usage(1, pymain->config.program);
pymain->status = 2; pymain->status = 2;
return 1; return 1;
} }
...@@ -1595,10 +1607,10 @@ pymain_parse_cmdline(_PyMain *pymain, _Py_CommandLineDetails *cmdline) ...@@ -1595,10 +1607,10 @@ pymain_parse_cmdline(_PyMain *pymain, _Py_CommandLineDetails *cmdline)
static const wchar_t* static const wchar_t*
pymain_get_xoption(_PyMain *pymain, wchar_t *name) config_get_xoption(_PyCoreConfig *config, wchar_t *name)
{ {
int nxoption = pymain->core_config.nxoption; int nxoption = config->nxoption;
wchar_t **xoptions = pymain->core_config.xoptions; wchar_t **xoptions = config->xoptions;
for (int i=0; i < nxoption; i++) { for (int i=0; i < nxoption; i++) {
wchar_t *option = xoptions[i]; wchar_t *option = xoptions[i];
size_t len; size_t len;
...@@ -1653,13 +1665,13 @@ pymain_wstr_to_int(const wchar_t *wstr, int *result) ...@@ -1653,13 +1665,13 @@ pymain_wstr_to_int(const wchar_t *wstr, int *result)
} }
static int static _PyInitError
pymain_init_tracemalloc(_PyMain *pymain) pymain_init_tracemalloc(_PyCoreConfig *config)
{ {
int nframe; int nframe;
int valid; int valid;
const char *env = pymain_get_env_var("PYTHONTRACEMALLOC"); const char *env = config_get_env_var("PYTHONTRACEMALLOC");
if (env) { if (env) {
if (!pymain_str_to_int(env, &nframe)) { if (!pymain_str_to_int(env, &nframe)) {
valid = (nframe >= 1); valid = (nframe >= 1);
...@@ -1668,14 +1680,13 @@ pymain_init_tracemalloc(_PyMain *pymain) ...@@ -1668,14 +1680,13 @@ pymain_init_tracemalloc(_PyMain *pymain)
valid = 0; valid = 0;
} }
if (!valid) { if (!valid) {
pymain->err = _Py_INIT_USER_ERR("PYTHONTRACEMALLOC: invalid " return _Py_INIT_USER_ERR("PYTHONTRACEMALLOC: invalid number "
"number of frames"); "of frames");
return -1;
} }
pymain->core_config.tracemalloc = nframe; config->tracemalloc = nframe;
} }
const wchar_t *xoption = pymain_get_xoption(pymain, L"tracemalloc"); const wchar_t *xoption = config_get_xoption(config, L"tracemalloc");
if (xoption) { if (xoption) {
const wchar_t *sep = wcschr(xoption, L'='); const wchar_t *sep = wcschr(xoption, L'=');
if (sep) { if (sep) {
...@@ -1686,25 +1697,24 @@ pymain_init_tracemalloc(_PyMain *pymain) ...@@ -1686,25 +1697,24 @@ pymain_init_tracemalloc(_PyMain *pymain)
valid = 0; valid = 0;
} }
if (!valid) { if (!valid) {
pymain->err = _Py_INIT_USER_ERR("-X tracemalloc=NFRAME: " return _Py_INIT_USER_ERR("-X tracemalloc=NFRAME: "
"invalid number of frames"); "invalid number of frames");
return -1;
} }
} }
else { else {
/* -X tracemalloc behaves as -X tracemalloc=1 */ /* -X tracemalloc behaves as -X tracemalloc=1 */
nframe = 1; nframe = 1;
} }
pymain->core_config.tracemalloc = nframe; config->tracemalloc = nframe;
} }
return 0; return _Py_INIT_OK();
} }
static void static void
pymain_get_env_flag(int *flag, const char *name) get_env_flag(int *flag, const char *name)
{ {
const char *var = pymain_get_env_var(name); const char *var = config_get_env_var(name);
if (!var) { if (!var) {
return; return;
} }
...@@ -1720,44 +1730,24 @@ pymain_get_env_flag(int *flag, const char *name) ...@@ -1720,44 +1730,24 @@ pymain_get_env_flag(int *flag, const char *name)
static void static void
pymain_get_env_flags(_PyMain *pymain, _Py_CommandLineDetails *cmdline) cmdline_get_env_flags(_Py_CommandLineDetails *cmdline)
{ {
pymain_get_env_flag(&cmdline->debug, get_env_flag(&cmdline->debug, "PYTHONDEBUG");
"PYTHONDEBUG"); get_env_flag(&cmdline->verbosity, "PYTHONVERBOSE");
pymain_get_env_flag(&cmdline->verbosity, get_env_flag(&cmdline->optimization_level, "PYTHONOPTIMIZE");
"PYTHONVERBOSE"); get_env_flag(&cmdline->inspect, "PYTHONINSPECT");
pymain_get_env_flag(&cmdline->optimization_level, get_env_flag(&cmdline->dont_write_bytecode, "PYTHONDONTWRITEBYTECODE");
"PYTHONOPTIMIZE"); get_env_flag(&cmdline->no_user_site_directory, "PYTHONNOUSERSITE");
pymain_get_env_flag(&cmdline->inspect, get_env_flag(&cmdline->use_unbuffered_io, "PYTHONUNBUFFERED");
"PYTHONINSPECT");
pymain_get_env_flag(&cmdline->dont_write_bytecode,
"PYTHONDONTWRITEBYTECODE");
pymain_get_env_flag(&cmdline->no_user_site_directory,
"PYTHONNOUSERSITE");
pymain_get_env_flag(&cmdline->use_unbuffered_io,
"PYTHONUNBUFFERED");
#ifdef MS_WINDOWS #ifdef MS_WINDOWS
pymain_get_env_flag(&cmdline->legacy_windows_fs_encoding, get_env_flag(&cmdline->legacy_windows_fs_encoding,
"PYTHONLEGACYWINDOWSFSENCODING"); "PYTHONLEGACYWINDOWSFSENCODING");
pymain_get_env_flag(&cmdline->legacy_windows_stdio, get_env_flag(&cmdline->legacy_windows_stdio,
"PYTHONLEGACYWINDOWSSTDIO"); "PYTHONLEGACYWINDOWSSTDIO");
#endif #endif
} }
static _PyInitError
config_init_module_search_path_env(_PyCoreConfig *config)
{
wchar_t *path;
int res = config_get_env_var_dup(&path, L"PYTHONPATH", "PYTHONPATH");
if (res < 0) {
return DECODE_LOCALE_ERR("PYTHONHOME", res);
}
config->module_search_path_env = path;
return _Py_INIT_OK();
}
static _PyInitError static _PyInitError
config_init_home(_PyCoreConfig *config) config_init_home(_PyCoreConfig *config)
{ {
...@@ -1786,7 +1776,7 @@ static _PyInitError ...@@ -1786,7 +1776,7 @@ static _PyInitError
config_init_hash_seed(_PyCoreConfig *config) config_init_hash_seed(_PyCoreConfig *config)
{ {
if (config->use_hash_seed < 0) { if (config->use_hash_seed < 0) {
const char *seed_text = pymain_get_env_var("PYTHONHASHSEED"); const char *seed_text = config_get_env_var("PYTHONHASHSEED");
int use_hash_seed; int use_hash_seed;
unsigned long hash_seed; unsigned long hash_seed;
if (_Py_ReadHashSeed(seed_text, &use_hash_seed, &hash_seed) < 0) { if (_Py_ReadHashSeed(seed_text, &use_hash_seed, &hash_seed) < 0) {
...@@ -1800,121 +1790,121 @@ config_init_hash_seed(_PyCoreConfig *config) ...@@ -1800,121 +1790,121 @@ config_init_hash_seed(_PyCoreConfig *config)
} }
static int static _PyInitError
pymain_init_utf8_mode(_PyMain *pymain, _Py_CommandLineDetails *cmdline) config_init_utf8_mode(_PyCoreConfig *config)
{ {
_PyCoreConfig *core_config = &pymain->core_config; /* The option was already set by Py_UTF8Mode,
Py_LegacyWindowsFSEncodingFlag or PYTHONLEGACYWINDOWSFSENCODING. */
#ifdef MS_WINDOWS if (config->utf8_mode >= 0) {
if (cmdline->legacy_windows_fs_encoding) { return _Py_INIT_OK();
core_config->utf8_mode = 0;
return 0;
} }
#endif
const wchar_t *xopt = pymain_get_xoption(pymain, L"utf8"); const wchar_t *xopt = config_get_xoption(config, L"utf8");
if (xopt) { if (xopt) {
wchar_t *sep = wcschr(xopt, L'='); wchar_t *sep = wcschr(xopt, L'=');
if (sep) { if (sep) {
xopt = sep + 1; xopt = sep + 1;
if (wcscmp(xopt, L"1") == 0) { if (wcscmp(xopt, L"1") == 0) {
core_config->utf8_mode = 1; config->utf8_mode = 1;
} }
else if (wcscmp(xopt, L"0") == 0) { else if (wcscmp(xopt, L"0") == 0) {
core_config->utf8_mode = 0; config->utf8_mode = 0;
} }
else { else {
pymain->err = _Py_INIT_USER_ERR("invalid -X utf8 option value"); return _Py_INIT_USER_ERR("invalid -X utf8 option value");
return -1;
} }
} }
else { else {
core_config->utf8_mode = 1; config->utf8_mode = 1;
} }
return 0; return _Py_INIT_OK();
} }
const char *opt = pymain_get_env_var("PYTHONUTF8"); const char *opt = config_get_env_var("PYTHONUTF8");
if (opt) { if (opt) {
if (strcmp(opt, "1") == 0) { if (strcmp(opt, "1") == 0) {
core_config->utf8_mode = 1; config->utf8_mode = 1;
} }
else if (strcmp(opt, "0") == 0) { else if (strcmp(opt, "0") == 0) {
core_config->utf8_mode = 0; config->utf8_mode = 0;
} }
else { else {
pymain->err = _Py_INIT_USER_ERR("invalid PYTHONUTF8 environment " return _Py_INIT_USER_ERR("invalid PYTHONUTF8 environment "
"variable value"); "variable value");
return -1;
} }
return 0; return _Py_INIT_OK();
} }
return 0;
return _Py_INIT_OK();
} }
static int static _PyInitError
pymain_parse_envvars(_PyMain *pymain, _Py_CommandLineDetails *cmdline) config_read_env_vars(_PyCoreConfig *config)
{ {
_PyCoreConfig *core_config = &pymain->core_config; config->allocator = config_get_env_var("PYTHONMALLOC");
/* Get environment variables */
pymain_get_env_flags(pymain, cmdline);
if (pymain_warnings_envvar(pymain, cmdline) < 0) {
return -1;
}
core_config->allocator = pymain_get_env_var("PYTHONMALLOC");
/* -X options */
if (pymain_get_xoption(pymain, L"showrefcount")) {
core_config->show_ref_count = 1;
}
if (pymain_get_xoption(pymain, L"showalloccount")) {
core_config->show_alloc_count = 1;
}
/* More complex options: env var and/or -X option */ if (config_get_env_var("PYTHONDUMPREFS")) {
if (pymain_get_env_var("PYTHONFAULTHANDLER") config->dump_refs = 1;
|| pymain_get_xoption(pymain, L"faulthandler")) {
core_config->faulthandler = 1;
}
if (pymain_get_env_var("PYTHONPROFILEIMPORTTIME")
|| pymain_get_xoption(pymain, L"importtime")) {
core_config->import_time = 1;
}
if (pymain_init_tracemalloc(pymain) < 0) {
return -1;
}
if (pymain_get_xoption(pymain, L"dev" ) ||
pymain_get_env_var("PYTHONDEVMODE"))
{
core_config->dev_mode = 1;
core_config->faulthandler = 1;
core_config->allocator = "debug";
}
if (pymain_get_env_var("PYTHONDUMPREFS")) {
pymain->core_config.dump_refs = 1;
} }
if (pymain_get_env_var("PYTHONMALLOCSTATS")) { if (config_get_env_var("PYTHONMALLOCSTATS")) {
pymain->core_config.malloc_stats = 1; config->malloc_stats = 1;
} }
const char* env = pymain_get_env_var("PYTHONCOERCECLOCALE"); const char *env = config_get_env_var("PYTHONCOERCECLOCALE");
if (env) { if (env) {
if (strcmp(env, "0") == 0) { if (strcmp(env, "0") == 0) {
pymain->core_config.coerce_c_locale = 0; config->coerce_c_locale = 0;
} }
else if (strcmp(env, "warn") == 0) { else if (strcmp(env, "warn") == 0) {
pymain->core_config.coerce_c_locale_warn = 1; config->coerce_c_locale_warn = 1;
} }
else { else {
pymain->core_config.coerce_c_locale = 1; config->coerce_c_locale = 1;
} }
} }
return 0; wchar_t *path;
int res = config_get_env_var_dup(&path, L"PYTHONPATH", "PYTHONPATH");
if (res < 0) {
return DECODE_LOCALE_ERR("PYTHONHOME", res);
}
config->module_search_path_env = path;
_PyInitError err = config_init_hash_seed(config);
if (_Py_INIT_FAILED(err)) {
return err;
}
return _Py_INIT_OK();
}
static _PyInitError
config_read_complex_options(_PyCoreConfig *config)
{
/* More complex options configured by env var and -X option */
if (config_get_env_var("PYTHONFAULTHANDLER")
|| config_get_xoption(config, L"faulthandler")) {
config->faulthandler = 1;
}
if (config_get_env_var("PYTHONPROFILEIMPORTTIME")
|| config_get_xoption(config, L"importtime")) {
config->import_time = 1;
}
if (config_get_xoption(config, L"dev" ) ||
config_get_env_var("PYTHONDEVMODE"))
{
config->dev_mode = 1;
config->faulthandler = 1;
config->allocator = "debug";
}
_PyInitError err = pymain_init_tracemalloc(config);
if (_Py_INIT_FAILED(err)) {
return err;
}
return _Py_INIT_OK();
} }
...@@ -1927,27 +1917,37 @@ pymain_parse_envvars(_PyMain *pymain, _Py_CommandLineDetails *cmdline) ...@@ -1927,27 +1917,37 @@ pymain_parse_envvars(_PyMain *pymain, _Py_CommandLineDetails *cmdline)
static int static int
pymain_read_conf_impl(_PyMain *pymain, _Py_CommandLineDetails *cmdline) pymain_read_conf_impl(_PyMain *pymain, _Py_CommandLineDetails *cmdline)
{ {
_PyInitError err;
int res = pymain_parse_cmdline(pymain, cmdline); int res = pymain_parse_cmdline(pymain, cmdline);
if (res != 0) { if (res != 0) {
return res; return res;
} }
if (pymain_init_core_argv(pymain, cmdline) < 0) {
return -1;
}
/* Set Py_IgnoreEnvironmentFlag for Py_GETENV() */ /* Set Py_IgnoreEnvironmentFlag for Py_GETENV() */
Py_IgnoreEnvironmentFlag = pymain->core_config.ignore_environment; _PyCoreConfig *config = &pymain->config;
Py_IgnoreEnvironmentFlag = config->ignore_environment;
if (pymain_parse_envvars(pymain, cmdline) < 0) { /* Get environment variables */
cmdline_get_env_flags(cmdline);
err = cmdline_init_env_warnoptions(cmdline);
if (_Py_INIT_FAILED(err)) {
pymain->err = err;
return -1; return -1;
} }
if (pymain_init_utf8_mode(pymain, cmdline) < 0) { #ifdef MS_WINDOWS
if (cmdline->legacy_windows_fs_encoding) {
config->utf8_mode = 0;
}
#endif
if (pymain_init_core_argv(pymain, cmdline) < 0) {
return -1; return -1;
} }
_PyInitError err = _PyCoreConfig_Read(&pymain->core_config); err = _PyCoreConfig_Read(config);
if (_Py_INIT_FAILED(err)) { if (_Py_INIT_FAILED(err)) {
pymain->err = err; pymain->err = err;
return -1; return -1;
...@@ -1979,10 +1979,10 @@ pymain_read_conf(_PyMain *pymain, _Py_CommandLineDetails *cmdline) ...@@ -1979,10 +1979,10 @@ pymain_read_conf(_PyMain *pymain, _Py_CommandLineDetails *cmdline)
int locale_coerced = 0; int locale_coerced = 0;
int loops = 0; int loops = 0;
int init_ignore_env = pymain->core_config.ignore_environment; int init_ignore_env = pymain->config.ignore_environment;
while (1) { while (1) {
int utf8_mode = pymain->core_config.utf8_mode; int utf8_mode = pymain->config.utf8_mode;
int encoding_changed = 0; int encoding_changed = 0;
/* Watchdog to prevent an infinite loop */ /* Watchdog to prevent an infinite loop */
...@@ -1997,8 +1997,9 @@ pymain_read_conf(_PyMain *pymain, _Py_CommandLineDetails *cmdline) ...@@ -1997,8 +1997,9 @@ pymain_read_conf(_PyMain *pymain, _Py_CommandLineDetails *cmdline)
goto done; goto done;
} }
res = pymain_read_conf_impl(pymain, cmdline); int conf_res = pymain_read_conf_impl(pymain, cmdline);
if (res != 0) { if (conf_res != 0) {
res = conf_res;
goto done; goto done;
} }
...@@ -2012,20 +2013,20 @@ pymain_read_conf(_PyMain *pymain, _Py_CommandLineDetails *cmdline) ...@@ -2012,20 +2013,20 @@ pymain_read_conf(_PyMain *pymain, _Py_CommandLineDetails *cmdline)
* See the documentation of the PYTHONCOERCECLOCALE setting for more * See the documentation of the PYTHONCOERCECLOCALE setting for more
* details. * details.
*/ */
if (pymain->core_config.coerce_c_locale == 1 && !locale_coerced) { if (pymain->config.coerce_c_locale == 1 && !locale_coerced) {
locale_coerced = 1; locale_coerced = 1;
_Py_CoerceLegacyLocale(&pymain->core_config); _Py_CoerceLegacyLocale(&pymain->config);
encoding_changed = 1; encoding_changed = 1;
} }
if (utf8_mode == -1) { if (utf8_mode == -1) {
if (pymain->core_config.utf8_mode == 1) { if (pymain->config.utf8_mode == 1) {
/* UTF-8 Mode enabled */ /* UTF-8 Mode enabled */
encoding_changed = 1; encoding_changed = 1;
} }
} }
else { else {
if (pymain->core_config.utf8_mode != utf8_mode) { if (pymain->config.utf8_mode != utf8_mode) {
encoding_changed = 1; encoding_changed = 1;
} }
} }
...@@ -2037,9 +2038,9 @@ pymain_read_conf(_PyMain *pymain, _Py_CommandLineDetails *cmdline) ...@@ -2037,9 +2038,9 @@ pymain_read_conf(_PyMain *pymain, _Py_CommandLineDetails *cmdline)
/* Reset the configuration, except UTF-8 Mode. Set Py_UTF8Mode for /* Reset the configuration, except UTF-8 Mode. Set Py_UTF8Mode for
Py_DecodeLocale(). Reset Py_IgnoreEnvironmentFlag, modified by Py_DecodeLocale(). Reset Py_IgnoreEnvironmentFlag, modified by
pymain_read_conf_impl(). */ pymain_read_conf_impl(). */
Py_UTF8Mode = pymain->core_config.utf8_mode; Py_UTF8Mode = pymain->config.utf8_mode;
Py_IgnoreEnvironmentFlag = init_ignore_env; Py_IgnoreEnvironmentFlag = init_ignore_env;
_PyCoreConfig_Clear(&pymain->core_config); _PyCoreConfig_Clear(&pymain->config);
pymain_clear_cmdline(pymain, cmdline); pymain_clear_cmdline(pymain, cmdline);
pymain_get_global_config(pymain, cmdline); pymain_get_global_config(pymain, cmdline);
...@@ -2059,6 +2060,34 @@ done: ...@@ -2059,6 +2060,34 @@ done:
} }
static void
config_init_locale(_PyCoreConfig *config)
{
if (config->utf8_mode >= 0 && config->coerce_c_locale >= 0) {
return;
}
if (_Py_LegacyLocaleDetected()) {
/* POSIX locale: enable C locale coercion and UTF-8 Mode */
if (config->utf8_mode < 0) {
config->utf8_mode = 1;
}
if (config->coerce_c_locale < 0) {
config->coerce_c_locale = 1;
}
return;
}
/* By default, C locale coercion and UTF-8 Mode are disabled */
if (config->coerce_c_locale < 0) {
config->coerce_c_locale = 0;
}
if (config->utf8_mode < 0) {
config->utf8_mode = 0;
}
}
/* Read configuration settings from standard locations /* Read configuration settings from standard locations
* *
* This function doesn't make any changes to the interpreter state - it * This function doesn't make any changes to the interpreter state - it
...@@ -2074,42 +2103,46 @@ done: ...@@ -2074,42 +2103,46 @@ done:
_PyInitError _PyInitError
_PyCoreConfig_Read(_PyCoreConfig *config) _PyCoreConfig_Read(_PyCoreConfig *config)
{ {
_PyInitError err = config_init_home(config); _PyInitError err;
err = config_read_env_vars(config);
if (_Py_INIT_FAILED(err)) { if (_Py_INIT_FAILED(err)) {
return err; return err;
} }
err = config_init_module_search_path_env(config); /* -X options */
if (config_get_xoption(config, L"showrefcount")) {
config->show_ref_count = 1;
}
if (config_get_xoption(config, L"showalloccount")) {
config->show_alloc_count = 1;
}
err = config_read_complex_options(config);
if (_Py_INIT_FAILED(err)) { if (_Py_INIT_FAILED(err)) {
return err; return err;
} }
err = config_init_program_name(config); err = config_init_utf8_mode(config);
if (_Py_INIT_FAILED(err)) { if (_Py_INIT_FAILED(err)) {
return err; return err;
} }
err = config_init_hash_seed(config); err = config_init_home(config);
if (_Py_INIT_FAILED(err)) { if (_Py_INIT_FAILED(err)) {
return err; return err;
} }
if (config->utf8_mode < 0 || config->coerce_c_locale < 0) { err = config_init_program_name(config);
if (_Py_LegacyLocaleDetected()) { if (_Py_INIT_FAILED(err)) {
if (config->utf8_mode < 0) { return err;
config->utf8_mode = 1; }
}
if (config->coerce_c_locale < 0) {
config->coerce_c_locale = 1;
}
}
if (config->coerce_c_locale < 0) { config_init_locale(config);
config->coerce_c_locale = 0;
} /* Signal handlers are installed by default */
if (config->utf8_mode < 0) { if (config->install_signal_handlers < 0) {
config->utf8_mode = 0; config->install_signal_handlers = 1;
}
} }
return _Py_INIT_OK(); return _Py_INIT_OK();
...@@ -2286,7 +2319,7 @@ _PyMainInterpreterConfig_Copy(_PyMainInterpreterConfig *config, ...@@ -2286,7 +2319,7 @@ _PyMainInterpreterConfig_Copy(_PyMainInterpreterConfig *config,
static PyObject * static PyObject *
config_create_path_list(const wchar_t *path, wchar_t delim) create_path_list(const wchar_t *path, wchar_t delim)
{ {
int i, n; int i, n;
const wchar_t *p; const wchar_t *p;
...@@ -2323,105 +2356,104 @@ config_create_path_list(const wchar_t *path, wchar_t delim) ...@@ -2323,105 +2356,104 @@ config_create_path_list(const wchar_t *path, wchar_t delim)
_PyInitError _PyInitError
_PyMainInterpreterConfig_Read(_PyMainInterpreterConfig *config, const _PyCoreConfig *core_config) _PyMainInterpreterConfig_Read(_PyMainInterpreterConfig *main_config,
const _PyCoreConfig *config)
{ {
_PyInitError err = _PyPathConfig_Init(core_config); _PyInitError err = _PyPathConfig_Init(config);
if (_Py_INIT_FAILED(err)) { if (_Py_INIT_FAILED(err)) {
return err; return err;
} }
if (config_init_argv(config, core_config) < 0) { if (main_config->install_signal_handlers < 0) {
return _Py_INIT_ERR("failed to create sys.argv"); main_config->install_signal_handlers = config->install_signal_handlers;
} }
if (config_init_warnoptions(config, core_config) < 0) { if (main_config->xoptions == NULL) {
return _Py_INIT_NO_MEMORY(); main_config->xoptions = config_create_xoptions_dict(config);
if (main_config->xoptions == NULL) {
return _Py_INIT_NO_MEMORY();
}
} }
/* Signal handlers are installed by default */ if (main_config->argv == NULL) {
if (config->install_signal_handlers < 0) { if (main_config_init_argv(main_config, config) < 0) {
config->install_signal_handlers = 1; return _Py_INIT_ERR("failed to create sys.argv");
}
} }
if (config->module_search_path == NULL && if (main_config->warnoptions == NULL) {
!core_config->_disable_importlib) if (main_config_init_warnoptions(main_config, config) < 0) {
return _Py_INIT_NO_MEMORY();
}
}
if (main_config->module_search_path == NULL &&
!config->_disable_importlib)
{ {
wchar_t *sys_path = Py_GetPath(); wchar_t *sys_path = Py_GetPath();
config->module_search_path = config_create_path_list(sys_path, DELIM); main_config->module_search_path = create_path_list(sys_path, DELIM);
if (config->module_search_path == NULL) { if (main_config->module_search_path == NULL) {
return _Py_INIT_NO_MEMORY(); return _Py_INIT_NO_MEMORY();
} }
} }
if (config->executable == NULL) { if (main_config->executable == NULL) {
config->executable = PyUnicode_FromWideChar(Py_GetProgramFullPath(), -1); main_config->executable = PyUnicode_FromWideChar(Py_GetProgramFullPath(), -1);
if (config->executable == NULL) { if (main_config->executable == NULL) {
return _Py_INIT_NO_MEMORY(); return _Py_INIT_NO_MEMORY();
} }
} }
if (config->prefix == NULL) { if (main_config->prefix == NULL) {
config->prefix = PyUnicode_FromWideChar(Py_GetPrefix(), -1); main_config->prefix = PyUnicode_FromWideChar(Py_GetPrefix(), -1);
if (config->prefix == NULL) { if (main_config->prefix == NULL) {
return _Py_INIT_NO_MEMORY(); return _Py_INIT_NO_MEMORY();
} }
} }
if (config->exec_prefix == NULL) { if (main_config->exec_prefix == NULL) {
config->exec_prefix = PyUnicode_FromWideChar(Py_GetExecPrefix(), -1); main_config->exec_prefix = PyUnicode_FromWideChar(Py_GetExecPrefix(), -1);
if (config->exec_prefix == NULL) { if (main_config->exec_prefix == NULL) {
return _Py_INIT_NO_MEMORY(); return _Py_INIT_NO_MEMORY();
} }
} }
if (config->base_prefix == NULL) { if (main_config->base_prefix == NULL) {
Py_INCREF(config->prefix); Py_INCREF(main_config->prefix);
config->base_prefix = config->prefix; main_config->base_prefix = main_config->prefix;
} }
if (config->base_exec_prefix == NULL) { if (main_config->base_exec_prefix == NULL) {
Py_INCREF(config->exec_prefix); Py_INCREF(main_config->exec_prefix);
config->base_exec_prefix = config->exec_prefix; main_config->base_exec_prefix = main_config->exec_prefix;
} }
return _Py_INIT_OK(); return _Py_INIT_OK();
} }
static int
pymain_init_python_core(_PyMain *pymain)
{
pymain_init_stdio(pymain);
pymain->err = _Py_InitializeCore(&pymain->core_config);
if (_Py_INIT_FAILED(pymain->err)) {
return -1;
}
return 0;
}
static int static int
pymain_init_python_main(_PyMain *pymain) pymain_init_python_main(_PyMain *pymain)
{ {
if (pymain_init_xoptions_dict(pymain)) { _PyInitError err;
pymain->err = _Py_INIT_NO_MEMORY();
return -1;
}
_PyInitError err = _PyMainInterpreterConfig_Read(&pymain->config, _PyMainInterpreterConfig main_config = _PyMainInterpreterConfig_INIT;
&pymain->core_config); err = _PyMainInterpreterConfig_Read(&main_config, &pymain->config);
if (_Py_INIT_FAILED(err)) { if (!_Py_INIT_FAILED(err)) {
pymain->err = err; err = _Py_InitializeMainInterpreter(&main_config);
return -1;
} }
_PyMainInterpreterConfig_Clear(&main_config);
err = _Py_InitializeMainInterpreter(&pymain->config);
if (_Py_INIT_FAILED(err)) { if (_Py_INIT_FAILED(err)) {
pymain->err = err; pymain->err = err;
return -1; return -1;
} }
return 0;
}
static int
pymain_init_sys_path(_PyMain *pymain)
{
if (pymain->filename != NULL) { if (pymain->filename != NULL) {
/* If filename is a package (ex: directory or ZIP file) which contains /* If filename is a package (ex: directory or ZIP file) which contains
__main__.py, main_importer_path is set to filename and will be __main__.py, main_importer_path is set to filename and will be
...@@ -2431,11 +2463,11 @@ pymain_init_python_main(_PyMain *pymain) ...@@ -2431,11 +2463,11 @@ pymain_init_python_main(_PyMain *pymain)
} }
PyObject *path0; PyObject *path0;
if (pymain_init_path0(pymain, &path0) < 0) { if (pymain_compute_path0(pymain, &path0) < 0) {
return -1; return -1;
} }
pymain_clear_configs(pymain); pymain_clear_config(pymain);
if (path0 != NULL) { if (path0 != NULL) {
if (pymain_update_sys_path(pymain, path0) < 0) { if (pymain_update_sys_path(pymain, path0) < 0) {
...@@ -2444,7 +2476,6 @@ pymain_init_python_main(_PyMain *pymain) ...@@ -2444,7 +2476,6 @@ pymain_init_python_main(_PyMain *pymain)
} }
Py_DECREF(path0); Py_DECREF(path0);
} }
return 0; return 0;
} }
...@@ -2466,6 +2497,7 @@ pymain_run_python(_PyMain *pymain) ...@@ -2466,6 +2497,7 @@ pymain_run_python(_PyMain *pymain)
else { else {
pymain_run_filename(pymain, &cf); pymain_run_filename(pymain, &cf);
} }
pymain_repl(pymain, &cf); pymain_repl(pymain, &cf);
} }
...@@ -2482,7 +2514,7 @@ pymain_init(_PyMain *pymain) ...@@ -2482,7 +2514,7 @@ pymain_init(_PyMain *pymain)
fedisableexcept(FE_OVERFLOW); fedisableexcept(FE_OVERFLOW);
#endif #endif
pymain->core_config._disable_importlib = 0; pymain->config._disable_importlib = 0;
pymain->config.install_signal_handlers = 1; pymain->config.install_signal_handlers = 1;
} }
...@@ -2505,7 +2537,7 @@ pymain_cmdline_impl(_PyMain *pymain, _Py_CommandLineDetails *cmdline) ...@@ -2505,7 +2537,7 @@ pymain_cmdline_impl(_PyMain *pymain, _Py_CommandLineDetails *cmdline)
} }
if (cmdline->print_help) { if (cmdline->print_help) {
pymain_usage(0, pymain->core_config.program); pymain_usage(0, pymain->config.program);
return 1; return 1;
} }
...@@ -2523,7 +2555,9 @@ pymain_cmdline_impl(_PyMain *pymain, _Py_CommandLineDetails *cmdline) ...@@ -2523,7 +2555,9 @@ pymain_cmdline_impl(_PyMain *pymain, _Py_CommandLineDetails *cmdline)
} }
orig_argc = pymain->argc; orig_argc = pymain->argc;
if (pymain_init_warnoptions(pymain, cmdline) < 0) { _PyInitError err = config_init_warnoptions(&pymain->config, cmdline);
if (_Py_INIT_FAILED(err)) {
pymain->err = err;
return -1; return -1;
} }
return 0; return 0;
...@@ -2571,7 +2605,10 @@ pymain_main(_PyMain *pymain) ...@@ -2571,7 +2605,10 @@ pymain_main(_PyMain *pymain)
goto done; goto done;
} }
if (pymain_init_python_core(pymain) < 0) { pymain_init_stdio(pymain);
pymain->err = _Py_InitializeCore(&pymain->config);
if (_Py_INIT_FAILED(pymain->err)) {
_Py_FatalInitError(pymain->err); _Py_FatalInitError(pymain->err);
} }
...@@ -2579,6 +2616,10 @@ pymain_main(_PyMain *pymain) ...@@ -2579,6 +2616,10 @@ pymain_main(_PyMain *pymain)
_Py_FatalInitError(pymain->err); _Py_FatalInitError(pymain->err);
} }
if (pymain_init_sys_path(pymain) < 0) {
_Py_FatalInitError(pymain->err);
}
pymain_run_python(pymain); pymain_run_python(pymain);
if (Py_FinalizeEx() < 0) { if (Py_FinalizeEx() < 0) {
......
...@@ -874,30 +874,29 @@ _Py_InitializeMainInterpreter(const _PyMainInterpreterConfig *config) ...@@ -874,30 +874,29 @@ _Py_InitializeMainInterpreter(const _PyMainInterpreterConfig *config)
_PyInitError _PyInitError
_Py_InitializeEx_Private(int install_sigs, int install_importlib) _Py_InitializeEx_Private(int install_sigs, int install_importlib)
{ {
_PyCoreConfig core_config = _PyCoreConfig_INIT; _PyCoreConfig config = _PyCoreConfig_INIT;
_PyMainInterpreterConfig config = _PyMainInterpreterConfig_INIT;
_PyInitError err; _PyInitError err;
core_config.ignore_environment = Py_IgnoreEnvironmentFlag; config.ignore_environment = Py_IgnoreEnvironmentFlag;
core_config._disable_importlib = !install_importlib; config._disable_importlib = !install_importlib;
config.install_signal_handlers = install_sigs; config.install_signal_handlers = install_sigs;
err = _PyCoreConfig_Read(&core_config); err = _PyCoreConfig_Read(&config);
if (_Py_INIT_FAILED(err)) { if (_Py_INIT_FAILED(err)) {
goto done; goto done;
} }
err = _Py_InitializeCore(&core_config); err = _Py_InitializeCore(&config);
if (_Py_INIT_FAILED(err)) { if (_Py_INIT_FAILED(err)) {
goto done; goto done;
} }
err = _PyMainInterpreterConfig_Read(&config, &core_config); _PyMainInterpreterConfig main_config = _PyMainInterpreterConfig_INIT;
if (_Py_INIT_FAILED(err)) { err = _PyMainInterpreterConfig_Read(&main_config, &config);
goto done; if (!_Py_INIT_FAILED(err)) {
err = _Py_InitializeMainInterpreter(&main_config);
} }
_PyMainInterpreterConfig_Clear(&main_config);
err = _Py_InitializeMainInterpreter(&config);
if (_Py_INIT_FAILED(err)) { if (_Py_INIT_FAILED(err)) {
goto done; goto done;
} }
...@@ -905,8 +904,7 @@ _Py_InitializeEx_Private(int install_sigs, int install_importlib) ...@@ -905,8 +904,7 @@ _Py_InitializeEx_Private(int install_sigs, int install_importlib)
err = _Py_INIT_OK(); err = _Py_INIT_OK();
done: done:
_PyCoreConfig_Clear(&core_config); _PyCoreConfig_Clear(&config);
_PyMainInterpreterConfig_Clear(&config);
return err; return err;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment