mirror of
https://github.com/python/cpython.git
synced 2025-09-26 18:29:57 +00:00
bpo-34170: Add _Py_InitializeFromConfig() (GH-8454)
* If _Py_InitializeCore() is called twice, the second call now copies and apply (partially) the new configuration. * Rename _Py_CommandLineDetails to _PyCmdline * Move more code into pymain_init(). The core configuration created by Py_Main() is new destroyed before running Python to reduce the memory footprint. * _Py_InitializeCore() now returns the created interpreter. _Py_InitializeMainInterpreter() now expects an interpreter. * Remove _Py_InitializeEx_Private(): _freeze_importlib now uses _Py_InitializeFromConfig() * _PyCoreConfig_InitPathConfig() now only computes the path configuration if needed.
This commit is contained in:
parent
6cf8255912
commit
1dc6e3906a
6 changed files with 305 additions and 208 deletions
|
@ -51,7 +51,9 @@ PyAPI_FUNC(int) Py_SetStandardStreamEncoding(const char *encoding,
|
||||||
const char *errors);
|
const char *errors);
|
||||||
|
|
||||||
/* PEP 432 Multi-phase initialization API (Private while provisional!) */
|
/* PEP 432 Multi-phase initialization API (Private while provisional!) */
|
||||||
PyAPI_FUNC(_PyInitError) _Py_InitializeCore(const _PyCoreConfig *);
|
PyAPI_FUNC(_PyInitError) _Py_InitializeCore(
|
||||||
|
PyInterpreterState **interp,
|
||||||
|
const _PyCoreConfig *);
|
||||||
PyAPI_FUNC(int) _Py_IsCoreInitialized(void);
|
PyAPI_FUNC(int) _Py_IsCoreInitialized(void);
|
||||||
|
|
||||||
PyAPI_FUNC(_PyInitError) _PyCoreConfig_Read(_PyCoreConfig *config);
|
PyAPI_FUNC(_PyInitError) _PyCoreConfig_Read(_PyCoreConfig *config);
|
||||||
|
@ -73,14 +75,17 @@ PyAPI_FUNC(int) _PyMainInterpreterConfig_Copy(
|
||||||
_PyMainInterpreterConfig *config,
|
_PyMainInterpreterConfig *config,
|
||||||
const _PyMainInterpreterConfig *config2);
|
const _PyMainInterpreterConfig *config2);
|
||||||
|
|
||||||
PyAPI_FUNC(_PyInitError) _Py_InitializeMainInterpreter(const _PyMainInterpreterConfig *);
|
PyAPI_FUNC(_PyInitError) _Py_InitializeMainInterpreter(
|
||||||
|
PyInterpreterState *interp,
|
||||||
|
const _PyMainInterpreterConfig *);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Initialization and finalization */
|
/* Initialization and finalization */
|
||||||
PyAPI_FUNC(void) Py_Initialize(void);
|
PyAPI_FUNC(void) Py_Initialize(void);
|
||||||
PyAPI_FUNC(void) Py_InitializeEx(int);
|
PyAPI_FUNC(void) Py_InitializeEx(int);
|
||||||
#ifndef Py_LIMITED_API
|
#ifndef Py_LIMITED_API
|
||||||
PyAPI_FUNC(_PyInitError) _Py_InitializeEx_Private(int, int);
|
PyAPI_FUNC(_PyInitError) _Py_InitializeFromConfig(
|
||||||
|
const _PyCoreConfig *config);
|
||||||
PyAPI_FUNC(void) _Py_FatalInitError(_PyInitError err) _Py_NO_RETURN;
|
PyAPI_FUNC(void) _Py_FatalInitError(_PyInitError err) _Py_NO_RETURN;
|
||||||
#endif
|
#endif
|
||||||
PyAPI_FUNC(void) Py_Finalize(void);
|
PyAPI_FUNC(void) Py_Finalize(void);
|
||||||
|
|
|
@ -200,8 +200,7 @@ typedef struct {
|
||||||
/* --- Private fields -------- */
|
/* --- Private fields -------- */
|
||||||
|
|
||||||
/* Install importlib? If set to 0, importlib is not initialized at all.
|
/* Install importlib? If set to 0, importlib is not initialized at all.
|
||||||
Needed by freeze_importlib: see install_importlib argument of
|
Needed by freeze_importlib. */
|
||||||
_Py_InitializeEx_Private(). */
|
|
||||||
int _install_importlib;
|
int _install_importlib;
|
||||||
|
|
||||||
/* Value of the --check-hash-based-pycs configure option. Valid values:
|
/* Value of the --check-hash-based-pycs configure option. Valid values:
|
||||||
|
|
218
Modules/main.c
218
Modules/main.c
|
@ -421,7 +421,7 @@ typedef struct {
|
||||||
wchar_t **env_warnoptions; /* PYTHONWARNINGS environment variables */
|
wchar_t **env_warnoptions; /* PYTHONWARNINGS environment variables */
|
||||||
int print_help; /* -h, -? options */
|
int print_help; /* -h, -? options */
|
||||||
int print_version; /* -V option */
|
int print_version; /* -V option */
|
||||||
} _Py_CommandLineDetails;
|
} _PyCmdline;
|
||||||
|
|
||||||
/* Structure used by Py_Main() to pass data to subfunctions */
|
/* Structure used by Py_Main() to pass data to subfunctions */
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -443,14 +443,10 @@ typedef struct {
|
||||||
wchar_t *command; /* -c argument */
|
wchar_t *command; /* -c argument */
|
||||||
wchar_t *module; /* -m argument */
|
wchar_t *module; /* -m argument */
|
||||||
|
|
||||||
_PyCoreConfig config;
|
|
||||||
|
|
||||||
PyObject *main_importer_path;
|
PyObject *main_importer_path;
|
||||||
} _PyMain;
|
} _PyMain;
|
||||||
|
|
||||||
#define _PyMain_INIT \
|
#define _PyMain_INIT {.err = _Py_INIT_OK()}
|
||||||
{.config = _PyCoreConfig_INIT, \
|
|
||||||
.err = _Py_INIT_OK()}
|
|
||||||
/* Note: _PyMain_INIT sets other fields to 0/NULL */
|
/* Note: _PyMain_INIT sets other fields to 0/NULL */
|
||||||
|
|
||||||
|
|
||||||
|
@ -502,7 +498,8 @@ pymain_wstrdup(_PyMain *pymain, const wchar_t *str)
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
pymain_init_cmdline_argv(_PyMain *pymain, _Py_CommandLineDetails *cmdline)
|
pymain_init_cmdline_argv(_PyMain *pymain, _PyCoreConfig *config,
|
||||||
|
_PyCmdline *cmdline)
|
||||||
{
|
{
|
||||||
assert(cmdline->argv == NULL);
|
assert(cmdline->argv == NULL);
|
||||||
|
|
||||||
|
@ -541,8 +538,8 @@ pymain_init_cmdline_argv(_PyMain *pymain, _Py_CommandLineDetails *cmdline)
|
||||||
else {
|
else {
|
||||||
program = L"";
|
program = L"";
|
||||||
}
|
}
|
||||||
pymain->config.program = pymain_wstrdup(pymain, program);
|
config->program = pymain_wstrdup(pymain, program);
|
||||||
if (pymain->config.program == NULL) {
|
if (config->program == NULL) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -767,7 +764,7 @@ _PyCoreConfig_Copy(_PyCoreConfig *config, const _PyCoreConfig *config2)
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
pymain_clear_cmdline(_PyMain *pymain, _Py_CommandLineDetails *cmdline)
|
pymain_clear_cmdline(_PyMain *pymain, _PyCmdline *cmdline)
|
||||||
{
|
{
|
||||||
PyMemAllocatorEx old_alloc;
|
PyMemAllocatorEx old_alloc;
|
||||||
_PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
|
_PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
|
||||||
|
@ -805,14 +802,14 @@ pymain_clear_pymain(_PyMain *pymain)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
pymain_clear_config(_PyMain *pymain)
|
pymain_clear_config(_PyCoreConfig *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->config);
|
_PyCoreConfig_Clear(config);
|
||||||
|
|
||||||
PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
|
PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
|
||||||
}
|
}
|
||||||
|
@ -849,8 +846,6 @@ pymain_free_raw(_PyMain *pymain)
|
||||||
Py_Initialize()-Py_Finalize() can be called multiple times. */
|
Py_Initialize()-Py_Finalize() can be called multiple times. */
|
||||||
_PyPathConfig_ClearGlobal();
|
_PyPathConfig_ClearGlobal();
|
||||||
|
|
||||||
pymain_clear_config(pymain);
|
|
||||||
|
|
||||||
/* Force the allocator used by pymain_read_conf() */
|
/* Force the allocator 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);
|
||||||
|
@ -940,10 +935,9 @@ pymain_wstrlist_append(_PyMain *pymain, int *len, wchar_t ***list, const wchar_t
|
||||||
Return 1 if parsing failed.
|
Return 1 if parsing failed.
|
||||||
Set pymain->err and return -1 on other errors. */
|
Set pymain->err and return -1 on other errors. */
|
||||||
static int
|
static int
|
||||||
pymain_parse_cmdline_impl(_PyMain *pymain, _Py_CommandLineDetails *cmdline)
|
pymain_parse_cmdline_impl(_PyMain *pymain, _PyCoreConfig *config,
|
||||||
|
_PyCmdline *cmdline)
|
||||||
{
|
{
|
||||||
_PyCoreConfig *config = &pymain->config;
|
|
||||||
|
|
||||||
_PyOS_ResetGetOpt();
|
_PyOS_ResetGetOpt();
|
||||||
do {
|
do {
|
||||||
int longindex = -1;
|
int longindex = -1;
|
||||||
|
@ -1185,7 +1179,7 @@ config_add_warnings_optlist(_PyCoreConfig *config, int len, wchar_t **options)
|
||||||
|
|
||||||
|
|
||||||
static _PyInitError
|
static _PyInitError
|
||||||
config_init_warnoptions(_PyCoreConfig *config, _Py_CommandLineDetails *cmdline)
|
config_init_warnoptions(_PyCoreConfig *config, _PyCmdline *cmdline)
|
||||||
{
|
{
|
||||||
_PyInitError err;
|
_PyInitError err;
|
||||||
|
|
||||||
|
@ -1256,14 +1250,14 @@ config_init_warnoptions(_PyCoreConfig *config, _Py_CommandLineDetails *cmdline)
|
||||||
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 _PyInitError
|
static _PyInitError
|
||||||
cmdline_init_env_warnoptions(_PyMain *pymain, _Py_CommandLineDetails *cmdline)
|
cmdline_init_env_warnoptions(_PyMain *pymain, _PyCoreConfig *config, _PyCmdline *cmdline)
|
||||||
{
|
{
|
||||||
if (pymain->config.ignore_environment) {
|
if (config->ignore_environment) {
|
||||||
return _Py_INIT_OK();
|
return _Py_INIT_OK();
|
||||||
}
|
}
|
||||||
|
|
||||||
wchar_t *env;
|
wchar_t *env;
|
||||||
int res = config_get_env_var_dup(&pymain->config, &env,
|
int res = config_get_env_var_dup(config, &env,
|
||||||
L"PYTHONWARNINGS", "PYTHONWARNINGS");
|
L"PYTHONWARNINGS", "PYTHONWARNINGS");
|
||||||
if (res < 0) {
|
if (res < 0) {
|
||||||
return DECODE_LOCALE_ERR("PYTHONWARNINGS", res);
|
return DECODE_LOCALE_ERR("PYTHONWARNINGS", res);
|
||||||
|
@ -1293,10 +1287,8 @@ cmdline_init_env_warnoptions(_PyMain *pymain, _Py_CommandLineDetails *cmdline)
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
pymain_init_stdio(_PyMain *pymain)
|
pymain_init_stdio(_PyMain *pymain, _PyCoreConfig *config)
|
||||||
{
|
{
|
||||||
_PyCoreConfig *config = &pymain->config;
|
|
||||||
|
|
||||||
pymain->stdin_is_interactive = (isatty(fileno(stdin))
|
pymain->stdin_is_interactive = (isatty(fileno(stdin))
|
||||||
|| config->interactive);
|
|| config->interactive);
|
||||||
|
|
||||||
|
@ -1339,8 +1331,6 @@ pymain_init_stdio(_PyMain *pymain)
|
||||||
static _PyInitError
|
static _PyInitError
|
||||||
config_init_program_name(_PyCoreConfig *config)
|
config_init_program_name(_PyCoreConfig *config)
|
||||||
{
|
{
|
||||||
assert(config->program_name == NULL);
|
|
||||||
|
|
||||||
/* If Py_SetProgramName() was called, use its value */
|
/* If Py_SetProgramName() was called, use its value */
|
||||||
const wchar_t *program_name = _Py_path_config.program_name;
|
const wchar_t *program_name = _Py_path_config.program_name;
|
||||||
if (program_name != NULL) {
|
if (program_name != NULL) {
|
||||||
|
@ -1434,7 +1424,7 @@ pymain_header(_PyMain *pymain)
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
pymain_init_core_argv(_PyMain *pymain, _Py_CommandLineDetails *cmdline)
|
pymain_init_core_argv(_PyMain *pymain, _PyCoreConfig *config, _PyCmdline *cmdline)
|
||||||
{
|
{
|
||||||
/* Copy argv to be able to modify it (to force -c/-m) */
|
/* Copy argv to be able to modify it (to force -c/-m) */
|
||||||
int argc = pymain->argc - _PyOS_optind;
|
int argc = pymain->argc - _PyOS_optind;
|
||||||
|
@ -1477,8 +1467,8 @@ pymain_init_core_argv(_PyMain *pymain, _Py_CommandLineDetails *cmdline)
|
||||||
argv[0] = arg0;
|
argv[0] = arg0;
|
||||||
}
|
}
|
||||||
|
|
||||||
pymain->config.argc = argc;
|
config->argc = argc;
|
||||||
pymain->config.argv = argv;
|
config->argv = argv;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1506,7 +1496,7 @@ wstrlist_as_pylist(int len, wchar_t **list)
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
pymain_compute_path0(_PyMain *pymain, PyObject **path0)
|
pymain_compute_path0(_PyMain *pymain, _PyCoreConfig *config, 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 */
|
||||||
|
@ -1519,8 +1509,8 @@ pymain_compute_path0(_PyMain *pymain, PyObject **path0)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
*path0 = _PyPathConfig_ComputeArgv0(pymain->config.argc,
|
*path0 = _PyPathConfig_ComputeArgv0(config->argc,
|
||||||
pymain->config.argv);
|
config->argv);
|
||||||
if (*path0 == NULL) {
|
if (*path0 == NULL) {
|
||||||
pymain->err = _Py_INIT_NO_MEMORY();
|
pymain->err = _Py_INIT_NO_MEMORY();
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -1573,7 +1563,7 @@ pymain_import_readline(_PyMain *pymain)
|
||||||
|
|
||||||
|
|
||||||
static FILE*
|
static FILE*
|
||||||
pymain_open_filename(_PyMain *pymain)
|
pymain_open_filename(_PyMain *pymain, _PyCoreConfig *config)
|
||||||
{
|
{
|
||||||
FILE* fp;
|
FILE* fp;
|
||||||
|
|
||||||
|
@ -1588,7 +1578,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->config.program, cfilename, err, strerror(err));
|
config->program, cfilename, err, strerror(err));
|
||||||
PyMem_RawFree(cfilename_buffer);
|
PyMem_RawFree(cfilename_buffer);
|
||||||
pymain->status = 2;
|
pymain->status = 2;
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -1611,7 +1601,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->config.program, pymain->filename);
|
config->program, pymain->filename);
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
pymain->status = 1;
|
pymain->status = 1;
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -1622,9 +1612,9 @@ pymain_open_filename(_PyMain *pymain)
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
pymain_run_startup(_PyMain *pymain, PyCompilerFlags *cf)
|
pymain_run_startup(_PyMain *pymain, _PyCoreConfig *config, PyCompilerFlags *cf)
|
||||||
{
|
{
|
||||||
const char *startup = config_get_env_var(&pymain->config, "PYTHONSTARTUP");
|
const char *startup = config_get_env_var(config, "PYTHONSTARTUP");
|
||||||
if (startup == NULL) {
|
if (startup == NULL) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1649,11 +1639,11 @@ pymain_run_startup(_PyMain *pymain, PyCompilerFlags *cf)
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
pymain_run_filename(_PyMain *pymain, PyCompilerFlags *cf)
|
pymain_run_filename(_PyMain *pymain, _PyCoreConfig *config, PyCompilerFlags *cf)
|
||||||
{
|
{
|
||||||
if (pymain->filename == NULL && pymain->stdin_is_interactive) {
|
if (pymain->filename == NULL && pymain->stdin_is_interactive) {
|
||||||
Py_InspectFlag = 0; /* do exit on SystemExit */
|
Py_InspectFlag = 0; /* do exit on SystemExit */
|
||||||
pymain_run_startup(pymain, cf);
|
pymain_run_startup(pymain, config, cf);
|
||||||
pymain_run_interactive_hook();
|
pymain_run_interactive_hook();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1664,7 +1654,7 @@ pymain_run_filename(_PyMain *pymain, PyCompilerFlags *cf)
|
||||||
|
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
if (pymain->filename != NULL) {
|
if (pymain->filename != NULL) {
|
||||||
fp = pymain_open_filename(pymain);
|
fp = pymain_open_filename(pymain, config);
|
||||||
if (fp == NULL) {
|
if (fp == NULL) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1678,11 +1668,11 @@ pymain_run_filename(_PyMain *pymain, PyCompilerFlags *cf)
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
pymain_repl(_PyMain *pymain, PyCompilerFlags *cf)
|
pymain_repl(_PyMain *pymain, _PyCoreConfig *config, 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 && config_get_env_var(&pymain->config, "PYTHONINSPECT")) {
|
if (!Py_InspectFlag && config_get_env_var(config, "PYTHONINSPECT")) {
|
||||||
Py_InspectFlag = 1;
|
Py_InspectFlag = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1705,14 +1695,15 @@ pymain_repl(_PyMain *pymain, PyCompilerFlags *cf)
|
||||||
Return 0 on success.
|
Return 0 on success.
|
||||||
Set pymain->err and return -1 on failure. */
|
Set pymain->err and return -1 on failure. */
|
||||||
static int
|
static int
|
||||||
pymain_parse_cmdline(_PyMain *pymain, _Py_CommandLineDetails *cmdline)
|
pymain_parse_cmdline(_PyMain *pymain, _PyCoreConfig *config,
|
||||||
|
_PyCmdline *cmdline)
|
||||||
{
|
{
|
||||||
int res = pymain_parse_cmdline_impl(pymain, cmdline);
|
int res = pymain_parse_cmdline_impl(pymain, config, cmdline);
|
||||||
if (res < 0) {
|
if (res < 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (res) {
|
if (res) {
|
||||||
pymain_usage(1, pymain->config.program);
|
pymain_usage(1, config->program);
|
||||||
pymain->status = 2;
|
pymain->status = 2;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -1881,10 +1872,9 @@ get_env_flag(_PyCoreConfig *config, int *flag, const char *name)
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
cmdline_get_env_flags(_PyMain *pymain, _Py_CommandLineDetails *cmdline)
|
cmdline_get_env_flags(_PyMain *pymain, _PyCoreConfig *config,
|
||||||
|
_PyCmdline *cmdline)
|
||||||
{
|
{
|
||||||
_PyCoreConfig *config = &pymain->config;
|
|
||||||
|
|
||||||
get_env_flag(config, &config->debug, "PYTHONDEBUG");
|
get_env_flag(config, &config->debug, "PYTHONDEBUG");
|
||||||
get_env_flag(config, &config->verbose, "PYTHONVERBOSE");
|
get_env_flag(config, &config->verbose, "PYTHONVERBOSE");
|
||||||
get_env_flag(config, &config->optimization_level, "PYTHONOPTIMIZE");
|
get_env_flag(config, &config->optimization_level, "PYTHONOPTIMIZE");
|
||||||
|
@ -2085,20 +2075,20 @@ config_read_complex_options(_PyCoreConfig *config)
|
||||||
Return 1 if Python is done and must exit.
|
Return 1 if Python is done and must exit.
|
||||||
Set pymain->err and return -1 on error. */
|
Set pymain->err and return -1 on error. */
|
||||||
static int
|
static int
|
||||||
pymain_read_conf_impl(_PyMain *pymain, _Py_CommandLineDetails *cmdline)
|
pymain_read_conf_impl(_PyMain *pymain, _PyCoreConfig *config,
|
||||||
|
_PyCmdline *cmdline)
|
||||||
{
|
{
|
||||||
_PyCoreConfig *config = &pymain->config;
|
|
||||||
_PyInitError err;
|
_PyInitError err;
|
||||||
|
|
||||||
int res = pymain_parse_cmdline(pymain, cmdline);
|
int res = pymain_parse_cmdline(pymain, config, cmdline);
|
||||||
if (res != 0) {
|
if (res != 0) {
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get environment variables */
|
/* Get environment variables */
|
||||||
cmdline_get_env_flags(pymain, cmdline);
|
cmdline_get_env_flags(pymain, config, cmdline);
|
||||||
|
|
||||||
err = cmdline_init_env_warnoptions(pymain, cmdline);
|
err = cmdline_init_env_warnoptions(pymain, config, cmdline);
|
||||||
if (_Py_INIT_FAILED(err)) {
|
if (_Py_INIT_FAILED(err)) {
|
||||||
pymain->err = err;
|
pymain->err = err;
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -2110,12 +2100,11 @@ pymain_read_conf_impl(_PyMain *pymain, _Py_CommandLineDetails *cmdline)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (pymain_init_core_argv(pymain, cmdline) < 0) {
|
if (pymain_init_core_argv(pymain, config, cmdline) < 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = _PyCoreConfig_Read(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;
|
||||||
|
@ -2127,9 +2116,9 @@ pymain_read_conf_impl(_PyMain *pymain, _Py_CommandLineDetails *cmdline)
|
||||||
/* Read the configuration, but initialize also the LC_CTYPE locale:
|
/* Read the configuration, but initialize also the LC_CTYPE locale:
|
||||||
enable UTF-8 mode (PEP 540) and/or coerce the C locale (PEP 538) */
|
enable UTF-8 mode (PEP 540) and/or coerce the C locale (PEP 538) */
|
||||||
static int
|
static int
|
||||||
pymain_read_conf(_PyMain *pymain, _Py_CommandLineDetails *cmdline)
|
pymain_read_conf(_PyMain *pymain, _PyCoreConfig *config,
|
||||||
|
_PyCmdline *cmdline)
|
||||||
{
|
{
|
||||||
_PyCoreConfig *config = &pymain->config;
|
|
||||||
_PyCoreConfig save_config = _PyCoreConfig_INIT;
|
_PyCoreConfig save_config = _PyCoreConfig_INIT;
|
||||||
char *oldloc = NULL;
|
char *oldloc = NULL;
|
||||||
int res = -1;
|
int res = -1;
|
||||||
|
@ -2163,11 +2152,11 @@ pymain_read_conf(_PyMain *pymain, _Py_CommandLineDetails *cmdline)
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pymain_init_cmdline_argv(pymain, cmdline) < 0) {
|
if (pymain_init_cmdline_argv(pymain, config, cmdline) < 0) {
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
int conf_res = pymain_read_conf_impl(pymain, cmdline);
|
int conf_res = pymain_read_conf_impl(pymain, config, cmdline);
|
||||||
if (conf_res != 0) {
|
if (conf_res != 0) {
|
||||||
res = conf_res;
|
res = conf_res;
|
||||||
goto done;
|
goto done;
|
||||||
|
@ -2214,7 +2203,7 @@ pymain_read_conf(_PyMain *pymain, _Py_CommandLineDetails *cmdline)
|
||||||
}
|
}
|
||||||
pymain_clear_cmdline(pymain, cmdline);
|
pymain_clear_cmdline(pymain, cmdline);
|
||||||
memset(cmdline, 0, sizeof(*cmdline));
|
memset(cmdline, 0, sizeof(*cmdline));
|
||||||
pymain->config.utf8_mode = new_utf8_mode;
|
config->utf8_mode = new_utf8_mode;
|
||||||
|
|
||||||
/* The encoding changed: read again the configuration
|
/* The encoding changed: read again the configuration
|
||||||
with the new encoding */
|
with the new encoding */
|
||||||
|
@ -2307,10 +2296,12 @@ _PyCoreConfig_Read(_PyCoreConfig *config)
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (config->program_name == NULL) {
|
||||||
err = config_init_program_name(config);
|
err = config_init_program_name(config);
|
||||||
if (_Py_INIT_FAILED(err)) {
|
if (_Py_INIT_FAILED(err)) {
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
config_init_locale(config);
|
config_init_locale(config);
|
||||||
|
|
||||||
|
@ -2419,7 +2410,7 @@ _PyMainInterpreterConfig_Read(_PyMainInterpreterConfig *main_config,
|
||||||
|
|
||||||
#define COPY_WSTR(ATTR) \
|
#define COPY_WSTR(ATTR) \
|
||||||
do { \
|
do { \
|
||||||
if (main_config->ATTR == NULL) { \
|
if (main_config->ATTR == NULL && config->ATTR != NULL) { \
|
||||||
main_config->ATTR = PyUnicode_FromWideChar(config->ATTR, -1); \
|
main_config->ATTR = PyUnicode_FromWideChar(config->ATTR, -1); \
|
||||||
if (main_config->ATTR == NULL) { \
|
if (main_config->ATTR == NULL) { \
|
||||||
return _Py_INIT_NO_MEMORY(); \
|
return _Py_INIT_NO_MEMORY(); \
|
||||||
|
@ -2468,14 +2459,15 @@ _PyMainInterpreterConfig_Read(_PyMainInterpreterConfig *main_config,
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
pymain_init_python_main(_PyMain *pymain)
|
pymain_init_python_main(_PyMain *pymain, _PyCoreConfig *config,
|
||||||
|
PyInterpreterState *interp)
|
||||||
{
|
{
|
||||||
_PyInitError err;
|
_PyInitError err;
|
||||||
|
|
||||||
_PyMainInterpreterConfig main_config = _PyMainInterpreterConfig_INIT;
|
_PyMainInterpreterConfig main_config = _PyMainInterpreterConfig_INIT;
|
||||||
err = _PyMainInterpreterConfig_Read(&main_config, &pymain->config);
|
err = _PyMainInterpreterConfig_Read(&main_config, config);
|
||||||
if (!_Py_INIT_FAILED(err)) {
|
if (!_Py_INIT_FAILED(err)) {
|
||||||
err = _Py_InitializeMainInterpreter(&main_config);
|
err = _Py_InitializeMainInterpreter(interp, &main_config);
|
||||||
}
|
}
|
||||||
_PyMainInterpreterConfig_Clear(&main_config);
|
_PyMainInterpreterConfig_Clear(&main_config);
|
||||||
|
|
||||||
|
@ -2488,7 +2480,7 @@ pymain_init_python_main(_PyMain *pymain)
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
pymain_init_sys_path(_PyMain *pymain)
|
pymain_init_sys_path(_PyMain *pymain, _PyCoreConfig *config)
|
||||||
{
|
{
|
||||||
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
|
||||||
|
@ -2499,12 +2491,10 @@ pymain_init_sys_path(_PyMain *pymain)
|
||||||
}
|
}
|
||||||
|
|
||||||
PyObject *path0;
|
PyObject *path0;
|
||||||
if (pymain_compute_path0(pymain, &path0) < 0) {
|
if (pymain_compute_path0(pymain, config, &path0) < 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
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) {
|
||||||
Py_DECREF(path0);
|
Py_DECREF(path0);
|
||||||
|
@ -2520,6 +2510,7 @@ static void
|
||||||
pymain_run_python(_PyMain *pymain)
|
pymain_run_python(_PyMain *pymain)
|
||||||
{
|
{
|
||||||
PyCompilerFlags cf = {.cf_flags = 0};
|
PyCompilerFlags cf = {.cf_flags = 0};
|
||||||
|
_PyCoreConfig *config = &PyThreadState_GET()->interp->core_config;
|
||||||
|
|
||||||
pymain_header(pymain);
|
pymain_header(pymain);
|
||||||
pymain_import_readline(pymain);
|
pymain_import_readline(pymain);
|
||||||
|
@ -2531,38 +2522,23 @@ pymain_run_python(_PyMain *pymain)
|
||||||
pymain->status = (pymain_run_module(pymain->module, 1) != 0);
|
pymain->status = (pymain_run_module(pymain->module, 1) != 0);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
pymain_run_filename(pymain, &cf);
|
pymain_run_filename(pymain, config, &cf);
|
||||||
}
|
}
|
||||||
|
|
||||||
pymain_repl(pymain, &cf);
|
pymain_repl(pymain, config, &cf);
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void
|
|
||||||
pymain_init(_PyMain *pymain)
|
|
||||||
{
|
|
||||||
/* 754 requires that FP exceptions run in "no stop" mode by default,
|
|
||||||
* and until C vendors implement C99's ways to control FP exceptions,
|
|
||||||
* Python requires non-stop mode. Alas, some platforms enable FP
|
|
||||||
* exceptions by default. Here we disable them.
|
|
||||||
*/
|
|
||||||
#ifdef __FreeBSD__
|
|
||||||
fedisableexcept(FE_OVERFLOW);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
pymain->config.install_signal_handlers = 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
pymain_cmdline_impl(_PyMain *pymain, _Py_CommandLineDetails *cmdline)
|
pymain_cmdline_impl(_PyMain *pymain, _PyCoreConfig *config,
|
||||||
|
_PyCmdline *cmdline)
|
||||||
{
|
{
|
||||||
pymain->err = _PyRuntime_Initialize();
|
pymain->err = _PyRuntime_Initialize();
|
||||||
if (_Py_INIT_FAILED(pymain->err)) {
|
if (_Py_INIT_FAILED(pymain->err)) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int res = pymain_read_conf(pymain, cmdline);
|
int res = pymain_read_conf(pymain, config, cmdline);
|
||||||
if (res < 0) {
|
if (res < 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -2572,7 +2548,7 @@ pymain_cmdline_impl(_PyMain *pymain, _Py_CommandLineDetails *cmdline)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cmdline->print_help) {
|
if (cmdline->print_help) {
|
||||||
pymain_usage(0, pymain->config.program);
|
pymain_usage(0, config->program);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2590,7 +2566,7 @@ pymain_cmdline_impl(_PyMain *pymain, _Py_CommandLineDetails *cmdline)
|
||||||
}
|
}
|
||||||
orig_argc = pymain->argc;
|
orig_argc = pymain->argc;
|
||||||
|
|
||||||
_PyInitError err = config_init_warnoptions(&pymain->config, cmdline);
|
_PyInitError err = config_init_warnoptions(config, cmdline);
|
||||||
if (_Py_INIT_FAILED(err)) {
|
if (_Py_INIT_FAILED(err)) {
|
||||||
pymain->err = err;
|
pymain->err = err;
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -2608,10 +2584,10 @@ pymain_cmdline_impl(_PyMain *pymain, _Py_CommandLineDetails *cmdline)
|
||||||
* Environment variables
|
* Environment variables
|
||||||
* Py_xxx global configuration variables
|
* Py_xxx global configuration variables
|
||||||
|
|
||||||
_Py_CommandLineDetails is a temporary structure used to prioritize these
|
_PyCmdline is a temporary structure used to prioritize these
|
||||||
variables. */
|
variables. */
|
||||||
static int
|
static int
|
||||||
pymain_cmdline(_PyMain *pymain)
|
pymain_cmdline(_PyMain *pymain, _PyCoreConfig *config)
|
||||||
{
|
{
|
||||||
/* Force default allocator, since pymain_free() and pymain_clear_config()
|
/* Force default allocator, since pymain_free() and pymain_clear_config()
|
||||||
must use the same allocator than this function. */
|
must use the same allocator than this function. */
|
||||||
|
@ -2622,10 +2598,10 @@ pymain_cmdline(_PyMain *pymain)
|
||||||
PyMem_GetAllocator(PYMEM_DOMAIN_RAW, &default_alloc);
|
PyMem_GetAllocator(PYMEM_DOMAIN_RAW, &default_alloc);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
_Py_CommandLineDetails cmdline;
|
_PyCmdline cmdline;
|
||||||
memset(&cmdline, 0, sizeof(cmdline));
|
memset(&cmdline, 0, sizeof(cmdline));
|
||||||
|
|
||||||
int res = pymain_cmdline_impl(pymain, &cmdline);
|
int res = pymain_cmdline_impl(pymain, config, &cmdline);
|
||||||
|
|
||||||
pymain_clear_cmdline(pymain, &cmdline);
|
pymain_clear_cmdline(pymain, &cmdline);
|
||||||
|
|
||||||
|
@ -2641,41 +2617,61 @@ pymain_cmdline(_PyMain *pymain)
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
pymain_main(_PyMain *pymain)
|
pymain_init(_PyMain *pymain)
|
||||||
{
|
{
|
||||||
pymain_init(pymain);
|
/* 754 requires that FP exceptions run in "no stop" mode by default,
|
||||||
|
* and until C vendors implement C99's ways to control FP exceptions,
|
||||||
|
* Python requires non-stop mode. Alas, some platforms enable FP
|
||||||
|
* exceptions by default. Here we disable them.
|
||||||
|
*/
|
||||||
|
#ifdef __FreeBSD__
|
||||||
|
fedisableexcept(FE_OVERFLOW);
|
||||||
|
#endif
|
||||||
|
|
||||||
_PyCoreConfig_GetGlobalConfig(&pymain->config);
|
_PyCoreConfig local_config = _PyCoreConfig_INIT;
|
||||||
|
_PyCoreConfig *config = &local_config;
|
||||||
|
config->install_signal_handlers = 1;
|
||||||
|
|
||||||
int res = pymain_cmdline(pymain);
|
_PyCoreConfig_GetGlobalConfig(config);
|
||||||
if (res < 0) {
|
|
||||||
|
int cmd_res = pymain_cmdline(pymain, config);
|
||||||
|
if (cmd_res < 0) {
|
||||||
_Py_FatalInitError(pymain->err);
|
_Py_FatalInitError(pymain->err);
|
||||||
}
|
}
|
||||||
if (res == 1) {
|
if (cmd_res == 1) {
|
||||||
goto done;
|
pymain_clear_config(config);
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
_PyCoreConfig_SetGlobalConfig(&pymain->config);
|
_PyCoreConfig_SetGlobalConfig(config);
|
||||||
|
|
||||||
pymain_init_stdio(pymain);
|
pymain_init_stdio(pymain, config);
|
||||||
|
|
||||||
/* bpo-34008: For backward compatibility reasons, calling Py_Main() after
|
PyInterpreterState *interp;
|
||||||
Py_Initialize() ignores the new configuration. */
|
pymain->err = _Py_InitializeCore(&interp, config);
|
||||||
if (!_PyRuntime.initialized) {
|
|
||||||
pymain->err = _Py_InitializeCore(&pymain->config);
|
|
||||||
if (_Py_INIT_FAILED(pymain->err)) {
|
if (_Py_INIT_FAILED(pymain->err)) {
|
||||||
_Py_FatalInitError(pymain->err);
|
_Py_FatalInitError(pymain->err);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (pymain_init_python_main(pymain) < 0) {
|
pymain_clear_config(config);
|
||||||
|
config = &interp->core_config;
|
||||||
|
|
||||||
|
if (pymain_init_python_main(pymain, config, interp) < 0) {
|
||||||
_Py_FatalInitError(pymain->err);
|
_Py_FatalInitError(pymain->err);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pymain_init_sys_path(pymain) < 0) {
|
if (pymain_init_sys_path(pymain, config) < 0) {
|
||||||
_Py_FatalInitError(pymain->err);
|
_Py_FatalInitError(pymain->err);
|
||||||
}
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
pymain_main(_PyMain *pymain)
|
||||||
|
{
|
||||||
|
int res = pymain_init(pymain);
|
||||||
|
if (res != 1) {
|
||||||
pymain_run_python(pymain);
|
pymain_run_python(pymain);
|
||||||
|
|
||||||
if (Py_FinalizeEx() < 0) {
|
if (Py_FinalizeEx() < 0) {
|
||||||
|
@ -2683,8 +2679,8 @@ pymain_main(_PyMain *pymain)
|
||||||
other special meaning */
|
other special meaning */
|
||||||
pymain->status = 120;
|
pymain->status = 120;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
done:
|
|
||||||
pymain_free(pymain);
|
pymain_free(pymain);
|
||||||
|
|
||||||
return pymain->status;
|
return pymain->status;
|
||||||
|
|
|
@ -74,14 +74,20 @@ main(int argc, char *argv[])
|
||||||
}
|
}
|
||||||
text[text_size] = '\0';
|
text[text_size] = '\0';
|
||||||
|
|
||||||
Py_NoUserSiteDirectory++;
|
_PyCoreConfig config = _PyCoreConfig_INIT;
|
||||||
Py_NoSiteFlag++;
|
config.user_site_directory = 0;
|
||||||
Py_IgnoreEnvironmentFlag++;
|
config.site_import = 0;
|
||||||
|
config.ignore_environment = 1;
|
||||||
|
config.program_name = L"./_freeze_importlib";
|
||||||
|
/* Don't install importlib, since it could execute outdated bytecode. */
|
||||||
|
config._install_importlib = 0;
|
||||||
|
config.install_signal_handlers = 1;
|
||||||
|
|
||||||
Py_FrozenFlag++;
|
Py_FrozenFlag++;
|
||||||
|
|
||||||
Py_SetProgramName(L"./_freeze_importlib");
|
_PyInitError err = _Py_InitializeFromConfig(&config);
|
||||||
/* Don't install importlib, since it could execute outdated bytecode. */
|
/* No need to call _PyCoreConfig_Clear() since we didn't allocate any
|
||||||
_PyInitError err = _Py_InitializeEx_Private(1, 0);
|
memory: program_name is a constant string. */
|
||||||
if (_Py_INIT_FAILED(err)) {
|
if (_Py_INIT_FAILED(err)) {
|
||||||
_Py_FatalInitError(err);
|
_Py_FatalInitError(err);
|
||||||
}
|
}
|
||||||
|
|
|
@ -282,8 +282,8 @@ core_config_init_module_search_paths(_PyCoreConfig *config,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
_PyInitError
|
static _PyInitError
|
||||||
_PyCoreConfig_InitPathConfig(_PyCoreConfig *config)
|
_PyCoreConfig_CalculatePathConfig(_PyCoreConfig *config)
|
||||||
{
|
{
|
||||||
_PyPathConfig path_config = _PyPathConfig_INIT;
|
_PyPathConfig path_config = _PyPathConfig_INIT;
|
||||||
_PyInitError err;
|
_PyInitError err;
|
||||||
|
@ -332,18 +332,6 @@ _PyCoreConfig_InitPathConfig(_PyCoreConfig *config)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (config->base_prefix == NULL) {
|
|
||||||
if (copy_wstr(&config->base_prefix, config->prefix) < 0) {
|
|
||||||
goto no_memory;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (config->base_exec_prefix == NULL) {
|
|
||||||
if (copy_wstr(&config->base_exec_prefix, config->exec_prefix) < 0) {
|
|
||||||
goto no_memory;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (path_config.isolated != -1) {
|
if (path_config.isolated != -1) {
|
||||||
config->isolated = path_config.isolated;
|
config->isolated = path_config.isolated;
|
||||||
}
|
}
|
||||||
|
@ -363,6 +351,39 @@ error:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
_PyInitError
|
||||||
|
_PyCoreConfig_InitPathConfig(_PyCoreConfig *config)
|
||||||
|
{
|
||||||
|
/* Do we need to calculate the path? */
|
||||||
|
if ((config->nmodule_search_path < 0)
|
||||||
|
|| (config->executable == NULL)
|
||||||
|
|| (config->prefix == NULL)
|
||||||
|
#ifdef MS_WINDOWS
|
||||||
|
|| (config->dll_path == NULL)
|
||||||
|
#endif
|
||||||
|
|| (config->exec_prefix == NULL))
|
||||||
|
{
|
||||||
|
_PyInitError err = _PyCoreConfig_CalculatePathConfig(config);
|
||||||
|
if (_Py_INIT_FAILED(err)) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (config->base_prefix == NULL) {
|
||||||
|
if (copy_wstr(&config->base_prefix, config->prefix) < 0) {
|
||||||
|
return _Py_INIT_NO_MEMORY();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (config->base_exec_prefix == NULL) {
|
||||||
|
if (copy_wstr(&config->base_exec_prefix, config->exec_prefix) < 0) {
|
||||||
|
return _Py_INIT_NO_MEMORY();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return _Py_INIT_OK();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
pathconfig_global_init(void)
|
pathconfig_global_init(void)
|
||||||
{
|
{
|
||||||
|
|
|
@ -567,7 +567,7 @@ _Py_SetLocaleFromEnv(int category)
|
||||||
/* Global initializations. Can be undone by Py_Finalize(). Don't
|
/* Global initializations. Can be undone by Py_Finalize(). Don't
|
||||||
call this twice without an intervening Py_Finalize() call.
|
call this twice without an intervening Py_Finalize() call.
|
||||||
|
|
||||||
Every call to Py_InitializeCore, Py_Initialize or Py_InitializeEx
|
Every call to _Py_InitializeCore, Py_Initialize or Py_InitializeEx
|
||||||
must have a corresponding call to Py_Finalize.
|
must have a corresponding call to Py_Finalize.
|
||||||
|
|
||||||
Locking: you must hold the interpreter lock while calling these APIs.
|
Locking: you must hold the interpreter lock while calling these APIs.
|
||||||
|
@ -576,6 +576,35 @@ _Py_SetLocaleFromEnv(int category)
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
static _PyInitError
|
||||||
|
_Py_Initialize_ReconfigureCore(PyInterpreterState *interp,
|
||||||
|
const _PyCoreConfig *core_config)
|
||||||
|
{
|
||||||
|
if (core_config->allocator != NULL) {
|
||||||
|
const char *allocator = _PyMem_GetAllocatorsName();
|
||||||
|
if (allocator == NULL || strcmp(core_config->allocator, allocator) != 0) {
|
||||||
|
return _Py_INIT_USER_ERR("cannot modify memory allocator "
|
||||||
|
"after first Py_Initialize()");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_PyCoreConfig_SetGlobalConfig(core_config);
|
||||||
|
|
||||||
|
if (_PyCoreConfig_Copy(&interp->core_config, core_config) < 0) {
|
||||||
|
return _Py_INIT_ERR("failed to copy core config");
|
||||||
|
}
|
||||||
|
core_config = &interp->core_config;
|
||||||
|
|
||||||
|
if (core_config->_install_importlib) {
|
||||||
|
_PyInitError err = _PyCoreConfig_SetPathConfig(core_config);
|
||||||
|
if (_Py_INIT_FAILED(err)) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return _Py_INIT_OK();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Begin interpreter initialization
|
/* Begin interpreter initialization
|
||||||
*
|
*
|
||||||
* On return, the first thread and interpreter state have been created,
|
* On return, the first thread and interpreter state have been created,
|
||||||
|
@ -592,16 +621,41 @@ _Py_SetLocaleFromEnv(int category)
|
||||||
* Any code invoked from this function should *not* assume it has access
|
* Any code invoked from this function should *not* assume it has access
|
||||||
* to the Python C API (unless the API is explicitly listed as being
|
* to the Python C API (unless the API is explicitly listed as being
|
||||||
* safe to call without calling Py_Initialize first)
|
* safe to call without calling Py_Initialize first)
|
||||||
|
*
|
||||||
|
* The caller is responsible to call _PyCoreConfig_Read().
|
||||||
*/
|
*/
|
||||||
|
|
||||||
_PyInitError
|
static _PyInitError
|
||||||
_Py_InitializeCore(const _PyCoreConfig *core_config)
|
_Py_InitializeCore_impl(PyInterpreterState **interp_p,
|
||||||
|
const _PyCoreConfig *core_config)
|
||||||
{
|
{
|
||||||
assert(core_config != NULL);
|
PyInterpreterState *interp;
|
||||||
|
_PyInitError err;
|
||||||
|
|
||||||
|
/* bpo-34008: For backward compatibility reasons, calling Py_Main() after
|
||||||
|
Py_Initialize() ignores the new configuration. */
|
||||||
|
if (_PyRuntime.core_initialized) {
|
||||||
|
PyThreadState *tstate = PyThreadState_GET();
|
||||||
|
if (!tstate) {
|
||||||
|
return _Py_INIT_ERR("failed to read thread state");
|
||||||
|
}
|
||||||
|
|
||||||
|
interp = tstate->interp;
|
||||||
|
if (interp == NULL) {
|
||||||
|
return _Py_INIT_ERR("can't make main interpreter");
|
||||||
|
}
|
||||||
|
*interp_p = interp;
|
||||||
|
|
||||||
|
return _Py_Initialize_ReconfigureCore(interp, core_config);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_PyRuntime.initialized) {
|
||||||
|
return _Py_INIT_ERR("main interpreter already initialized");
|
||||||
|
}
|
||||||
|
|
||||||
_PyCoreConfig_SetGlobalConfig(core_config);
|
_PyCoreConfig_SetGlobalConfig(core_config);
|
||||||
|
|
||||||
_PyInitError err = _PyRuntime_Initialize();
|
err = _PyRuntime_Initialize();
|
||||||
if (_Py_INIT_FAILED(err)) {
|
if (_Py_INIT_FAILED(err)) {
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
@ -612,13 +666,6 @@ _Py_InitializeCore(const _PyCoreConfig *core_config)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_PyRuntime.initialized) {
|
|
||||||
return _Py_INIT_ERR("main interpreter already initialized");
|
|
||||||
}
|
|
||||||
if (_PyRuntime.core_initialized) {
|
|
||||||
return _Py_INIT_ERR("runtime core already initialized");
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Py_Finalize leaves _Py_Finalizing set in order to help daemon
|
/* Py_Finalize leaves _Py_Finalizing set in order to help daemon
|
||||||
* threads behave a little more gracefully at interpreter shutdown.
|
* threads behave a little more gracefully at interpreter shutdown.
|
||||||
* We clobber it here so the new interpreter can start with a clean
|
* We clobber it here so the new interpreter can start with a clean
|
||||||
|
@ -648,10 +695,11 @@ _Py_InitializeCore(const _PyCoreConfig *core_config)
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
PyInterpreterState *interp = PyInterpreterState_New();
|
interp = PyInterpreterState_New();
|
||||||
if (interp == NULL) {
|
if (interp == NULL) {
|
||||||
return _Py_INIT_ERR("can't make main interpreter");
|
return _Py_INIT_ERR("can't make main interpreter");
|
||||||
}
|
}
|
||||||
|
*interp_p = interp;
|
||||||
|
|
||||||
if (_PyCoreConfig_Copy(&interp->core_config, core_config) < 0) {
|
if (_PyCoreConfig_Copy(&interp->core_config, core_config) < 0) {
|
||||||
return _Py_INIT_ERR("failed to copy core config");
|
return _Py_INIT_ERR("failed to copy core config");
|
||||||
|
@ -773,6 +821,43 @@ _Py_InitializeCore(const _PyCoreConfig *core_config)
|
||||||
return _Py_INIT_OK();
|
return _Py_INIT_OK();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_PyInitError
|
||||||
|
_Py_InitializeCore(PyInterpreterState **interp_p,
|
||||||
|
const _PyCoreConfig *src_config)
|
||||||
|
{
|
||||||
|
assert(src_config != NULL);
|
||||||
|
|
||||||
|
|
||||||
|
PyMemAllocatorEx old_alloc;
|
||||||
|
_PyInitError err;
|
||||||
|
|
||||||
|
/* Copy the configuration, since _PyCoreConfig_Read() modifies it
|
||||||
|
(and the input configuration is read only). */
|
||||||
|
_PyCoreConfig config = _PyCoreConfig_INIT;
|
||||||
|
|
||||||
|
_PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
|
||||||
|
if (_PyCoreConfig_Copy(&config, src_config) >= 0) {
|
||||||
|
err = _PyCoreConfig_Read(&config);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
err = _Py_INIT_ERR("failed to copy core config");
|
||||||
|
}
|
||||||
|
PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
|
||||||
|
|
||||||
|
if (_Py_INIT_FAILED(err)) {
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = _Py_InitializeCore_impl(interp_p, &config);
|
||||||
|
|
||||||
|
done:
|
||||||
|
_PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
|
||||||
|
_PyCoreConfig_Clear(&config);
|
||||||
|
PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
/* Py_Initialize() has already been called: update the main interpreter
|
/* Py_Initialize() has already been called: update the main interpreter
|
||||||
configuration. Example of bpo-34008: Py_Main() called after
|
configuration. Example of bpo-34008: Py_Main() called after
|
||||||
Py_Initialize(). */
|
Py_Initialize(). */
|
||||||
|
@ -801,27 +886,19 @@ _Py_ReconfigureMainInterpreter(PyInterpreterState *interp,
|
||||||
* non-zero return code.
|
* non-zero return code.
|
||||||
*/
|
*/
|
||||||
_PyInitError
|
_PyInitError
|
||||||
_Py_InitializeMainInterpreter(const _PyMainInterpreterConfig *config)
|
_Py_InitializeMainInterpreter(PyInterpreterState *interp,
|
||||||
|
const _PyMainInterpreterConfig *config)
|
||||||
{
|
{
|
||||||
if (!_PyRuntime.core_initialized) {
|
if (!_PyRuntime.core_initialized) {
|
||||||
return _Py_INIT_ERR("runtime core not initialized");
|
return _Py_INIT_ERR("runtime core not initialized");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get current thread state and interpreter pointer */
|
/* Configure the main interpreter */
|
||||||
PyThreadState *tstate = PyThreadState_GET();
|
|
||||||
if (!tstate) {
|
|
||||||
return _Py_INIT_ERR("failed to read thread state");
|
|
||||||
}
|
|
||||||
PyInterpreterState *interp = tstate->interp;
|
|
||||||
if (!interp) {
|
|
||||||
return _Py_INIT_ERR("failed to get interpreter");
|
|
||||||
}
|
|
||||||
_PyCoreConfig *core_config = &interp->core_config;
|
|
||||||
|
|
||||||
/* Now finish configuring the main interpreter */
|
|
||||||
if (_PyMainInterpreterConfig_Copy(&interp->config, config) < 0) {
|
if (_PyMainInterpreterConfig_Copy(&interp->config, config) < 0) {
|
||||||
return _Py_INIT_ERR("failed to copy main interpreter config");
|
return _Py_INIT_ERR("failed to copy main interpreter config");
|
||||||
}
|
}
|
||||||
|
config = &interp->config;
|
||||||
|
_PyCoreConfig *core_config = &interp->core_config;
|
||||||
|
|
||||||
if (_PyRuntime.initialized) {
|
if (_PyRuntime.initialized) {
|
||||||
return _Py_ReconfigureMainInterpreter(interp, config);
|
return _Py_ReconfigureMainInterpreter(interp, config);
|
||||||
|
@ -908,51 +985,44 @@ _Py_InitializeMainInterpreter(const _PyMainInterpreterConfig *config)
|
||||||
#undef _INIT_DEBUG_PRINT
|
#undef _INIT_DEBUG_PRINT
|
||||||
|
|
||||||
_PyInitError
|
_PyInitError
|
||||||
_Py_InitializeEx_Private(int install_sigs, int install_importlib)
|
_Py_InitializeFromConfig(const _PyCoreConfig *config)
|
||||||
{
|
{
|
||||||
if (_PyRuntime.initialized) {
|
PyInterpreterState *interp;
|
||||||
/* bpo-33932: Calling Py_Initialize() twice does nothing. */
|
|
||||||
return _Py_INIT_OK();
|
|
||||||
}
|
|
||||||
|
|
||||||
_PyCoreConfig config = _PyCoreConfig_INIT;
|
|
||||||
_PyInitError err;
|
_PyInitError err;
|
||||||
|
err = _Py_InitializeCore(&interp, config);
|
||||||
config._install_importlib = install_importlib;
|
|
||||||
config.install_signal_handlers = install_sigs;
|
|
||||||
|
|
||||||
err = _PyCoreConfig_Read(&config);
|
|
||||||
if (_Py_INIT_FAILED(err)) {
|
if (_Py_INIT_FAILED(err)) {
|
||||||
goto done;
|
return err;
|
||||||
}
|
|
||||||
|
|
||||||
err = _Py_InitializeCore(&config);
|
|
||||||
if (_Py_INIT_FAILED(err)) {
|
|
||||||
goto done;
|
|
||||||
}
|
}
|
||||||
|
config = &interp->core_config;
|
||||||
|
|
||||||
_PyMainInterpreterConfig main_config = _PyMainInterpreterConfig_INIT;
|
_PyMainInterpreterConfig main_config = _PyMainInterpreterConfig_INIT;
|
||||||
err = _PyMainInterpreterConfig_Read(&main_config, &config);
|
err = _PyMainInterpreterConfig_Read(&main_config, config);
|
||||||
if (!_Py_INIT_FAILED(err)) {
|
if (!_Py_INIT_FAILED(err)) {
|
||||||
err = _Py_InitializeMainInterpreter(&main_config);
|
err = _Py_InitializeMainInterpreter(interp, &main_config);
|
||||||
}
|
}
|
||||||
_PyMainInterpreterConfig_Clear(&main_config);
|
_PyMainInterpreterConfig_Clear(&main_config);
|
||||||
if (_Py_INIT_FAILED(err)) {
|
if (_Py_INIT_FAILED(err)) {
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
|
|
||||||
err = _Py_INIT_OK();
|
|
||||||
|
|
||||||
done:
|
|
||||||
_PyCoreConfig_Clear(&config);
|
|
||||||
return err;
|
return err;
|
||||||
|
}
|
||||||
|
return _Py_INIT_OK();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
Py_InitializeEx(int install_sigs)
|
Py_InitializeEx(int install_sigs)
|
||||||
{
|
{
|
||||||
_PyInitError err = _Py_InitializeEx_Private(install_sigs, 1);
|
if (_PyRuntime.initialized) {
|
||||||
|
/* bpo-33932: Calling Py_Initialize() twice does nothing. */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_PyInitError err;
|
||||||
|
_PyCoreConfig config = _PyCoreConfig_INIT;
|
||||||
|
config.install_signal_handlers = install_sigs;
|
||||||
|
|
||||||
|
err = _Py_InitializeFromConfig(&config);
|
||||||
|
_PyCoreConfig_Clear(&config);
|
||||||
|
|
||||||
if (_Py_INIT_FAILED(err)) {
|
if (_Py_INIT_FAILED(err)) {
|
||||||
_Py_FatalInitError(err);
|
_Py_FatalInitError(err);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue