bpo-34170: Enhance _PyCoreConfig_Read() (GH-8468)
* Inline cmdline_get_env_flags() into config_read_env_vars(): _PyCoreConfig_Read() now reads much more environment variables like PYTHONVERBOSE. * Allow to override faulthandler and allocator even if dev_mode=1. PYTHONMALLOC is now the priority over PYTHONDEVMODE. * Fix _PyCoreConfig_Copy(): copy also install_signal_handlers, coerce_c_locale and coerce_c_locale_warn * _PyCoreConfig.install_signal_handlers default is now 1: install signals by default * Fix also a compiler warning: don't define _PyPathConfig type twice.
This commit is contained in:
parent
48ed88a93b
commit
ecf411c59e
|
@ -127,10 +127,9 @@ PyAPI_FUNC(wchar_t *) Py_GetExecPrefix(void);
|
||||||
PyAPI_FUNC(wchar_t *) Py_GetPath(void);
|
PyAPI_FUNC(wchar_t *) Py_GetPath(void);
|
||||||
#ifdef Py_BUILD_CORE
|
#ifdef Py_BUILD_CORE
|
||||||
struct _PyPathConfig;
|
struct _PyPathConfig;
|
||||||
typedef struct _PyPathConfig _PyPathConfig;
|
|
||||||
|
|
||||||
PyAPI_FUNC(_PyInitError) _PyPathConfig_SetGlobal(
|
PyAPI_FUNC(_PyInitError) _PyPathConfig_SetGlobal(
|
||||||
const _PyPathConfig *config);
|
const struct _PyPathConfig *config);
|
||||||
PyAPI_FUNC(PyObject*) _PyPathConfig_ComputeArgv0(int argc, wchar_t **argv);
|
PyAPI_FUNC(PyObject*) _PyPathConfig_ComputeArgv0(int argc, wchar_t **argv);
|
||||||
PyAPI_FUNC(int) _Py_FindEnvConfigValue(
|
PyAPI_FUNC(int) _Py_FindEnvConfigValue(
|
||||||
FILE *env_file,
|
FILE *env_file,
|
||||||
|
|
|
@ -26,15 +26,23 @@ typedef PyObject* (*_PyFrameEvalFunction)(struct _frame *, int);
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int install_signal_handlers; /* Install signal handlers? -1 means unset */
|
/* Install signal handlers? Yes by default. */
|
||||||
|
int install_signal_handlers;
|
||||||
|
|
||||||
int ignore_environment; /* -E, Py_IgnoreEnvironmentFlag, -1 means unset */
|
int ignore_environment; /* -E, Py_IgnoreEnvironmentFlag, -1 means unset */
|
||||||
int use_hash_seed; /* PYTHONHASHSEED=x */
|
int use_hash_seed; /* PYTHONHASHSEED=x */
|
||||||
unsigned long hash_seed;
|
unsigned long hash_seed;
|
||||||
const char *allocator; /* Memory allocator: _PyMem_SetupAllocators() */
|
const char *allocator; /* Memory allocator: PYTHONMALLOC */
|
||||||
int dev_mode; /* PYTHONDEVMODE, -X dev */
|
int dev_mode; /* PYTHONDEVMODE, -X dev */
|
||||||
int faulthandler; /* PYTHONFAULTHANDLER, -X faulthandler */
|
|
||||||
int tracemalloc; /* PYTHONTRACEMALLOC, -X tracemalloc=N */
|
/* Enable faulthandler?
|
||||||
|
Set to 1 by -X faulthandler and PYTHONFAULTHANDLER. -1 means unset. */
|
||||||
|
int faulthandler;
|
||||||
|
|
||||||
|
/* Enable tracemalloc?
|
||||||
|
Set by -X tracemalloc=N and PYTHONTRACEMALLOC. -1 means unset */
|
||||||
|
int tracemalloc;
|
||||||
|
|
||||||
int import_time; /* PYTHONPROFILEIMPORTTIME, -X importtime */
|
int import_time; /* PYTHONPROFILEIMPORTTIME, -X importtime */
|
||||||
int show_ref_count; /* -X showrefcount */
|
int show_ref_count; /* -X showrefcount */
|
||||||
int show_alloc_count; /* -X showalloccount */
|
int show_alloc_count; /* -X showalloccount */
|
||||||
|
@ -229,9 +237,10 @@ typedef struct {
|
||||||
|
|
||||||
#define _PyCoreConfig_INIT \
|
#define _PyCoreConfig_INIT \
|
||||||
(_PyCoreConfig){ \
|
(_PyCoreConfig){ \
|
||||||
.install_signal_handlers = -1, \
|
.install_signal_handlers = 1, \
|
||||||
.ignore_environment = -1, \
|
.ignore_environment = -1, \
|
||||||
.use_hash_seed = -1, \
|
.use_hash_seed = -1, \
|
||||||
|
.faulthandler = -1, \
|
||||||
.tracemalloc = -1, \
|
.tracemalloc = -1, \
|
||||||
.coerce_c_locale = -1, \
|
.coerce_c_locale = -1, \
|
||||||
.utf8_mode = -1, \
|
.utf8_mode = -1, \
|
||||||
|
|
|
@ -551,9 +551,7 @@ class CmdLineTest(unittest.TestCase):
|
||||||
env = dict(os.environ)
|
env = dict(os.environ)
|
||||||
env.pop('PYTHONWARNINGS', None)
|
env.pop('PYTHONWARNINGS', None)
|
||||||
env.pop('PYTHONDEVMODE', None)
|
env.pop('PYTHONDEVMODE', None)
|
||||||
# Force malloc() to disable the debug hooks which are enabled
|
env.pop('PYTHONMALLOC', None)
|
||||||
# by default for Python compiled in debug mode
|
|
||||||
env['PYTHONMALLOC'] = 'malloc'
|
|
||||||
|
|
||||||
if xdev:
|
if xdev:
|
||||||
args = (sys.executable, '-X', 'dev', *args)
|
args = (sys.executable, '-X', 'dev', *args)
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
-X dev: it is now possible to override the memory allocator using
|
||||||
|
PYTHONMALLOC even if the developer mode is enabled.
|
146
Modules/main.c
146
Modules/main.c
|
@ -701,6 +701,7 @@ _PyCoreConfig_Copy(_PyCoreConfig *config, const _PyCoreConfig *config2)
|
||||||
config->LEN = config2->LEN; \
|
config->LEN = config2->LEN; \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
|
COPY_ATTR(install_signal_handlers);
|
||||||
COPY_ATTR(ignore_environment);
|
COPY_ATTR(ignore_environment);
|
||||||
COPY_ATTR(use_hash_seed);
|
COPY_ATTR(use_hash_seed);
|
||||||
COPY_ATTR(hash_seed);
|
COPY_ATTR(hash_seed);
|
||||||
|
@ -714,6 +715,9 @@ _PyCoreConfig_Copy(_PyCoreConfig *config, const _PyCoreConfig *config2)
|
||||||
COPY_ATTR(show_alloc_count);
|
COPY_ATTR(show_alloc_count);
|
||||||
COPY_ATTR(dump_refs);
|
COPY_ATTR(dump_refs);
|
||||||
COPY_ATTR(malloc_stats);
|
COPY_ATTR(malloc_stats);
|
||||||
|
|
||||||
|
COPY_ATTR(coerce_c_locale);
|
||||||
|
COPY_ATTR(coerce_c_locale_warn);
|
||||||
COPY_ATTR(utf8_mode);
|
COPY_ATTR(utf8_mode);
|
||||||
|
|
||||||
COPY_STR_ATTR(pycache_prefix);
|
COPY_STR_ATTR(pycache_prefix);
|
||||||
|
@ -1244,9 +1248,7 @@ config_init_warnoptions(_PyCoreConfig *config, _PyCmdline *cmdline)
|
||||||
static _PyInitError
|
static _PyInitError
|
||||||
cmdline_init_env_warnoptions(_PyMain *pymain, _PyCoreConfig *config, _PyCmdline *cmdline)
|
cmdline_init_env_warnoptions(_PyMain *pymain, _PyCoreConfig *config, _PyCmdline *cmdline)
|
||||||
{
|
{
|
||||||
if (config->ignore_environment) {
|
assert(!config->ignore_environment);
|
||||||
return _Py_INIT_OK();
|
|
||||||
}
|
|
||||||
|
|
||||||
wchar_t *env;
|
wchar_t *env;
|
||||||
int res = config_get_env_var_dup(config, &env,
|
int res = config_get_env_var_dup(config, &env,
|
||||||
|
@ -1819,37 +1821,6 @@ get_env_flag(_PyCoreConfig *config, int *flag, const char *name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
|
||||||
cmdline_get_env_flags(_PyMain *pymain, _PyCoreConfig *config,
|
|
||||||
_PyCmdline *cmdline)
|
|
||||||
{
|
|
||||||
get_env_flag(config, &config->debug, "PYTHONDEBUG");
|
|
||||||
get_env_flag(config, &config->verbose, "PYTHONVERBOSE");
|
|
||||||
get_env_flag(config, &config->optimization_level, "PYTHONOPTIMIZE");
|
|
||||||
get_env_flag(config, &config->inspect, "PYTHONINSPECT");
|
|
||||||
|
|
||||||
int dont_write_bytecode = 0;
|
|
||||||
get_env_flag(config, &dont_write_bytecode, "PYTHONDONTWRITEBYTECODE");
|
|
||||||
if (dont_write_bytecode) {
|
|
||||||
config->write_bytecode = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int no_user_site_directory = 0;
|
|
||||||
get_env_flag(config, &no_user_site_directory, "PYTHONNOUSERSITE");
|
|
||||||
if (no_user_site_directory) {
|
|
||||||
config->user_site_directory = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
get_env_flag(config, &config->unbuffered_stdio, "PYTHONUNBUFFERED");
|
|
||||||
#ifdef MS_WINDOWS
|
|
||||||
get_env_flag(config, &config->legacy_windows_fs_encoding,
|
|
||||||
"PYTHONLEGACYWINDOWSFSENCODING");
|
|
||||||
get_env_flag(config, &config->legacy_windows_stdio,
|
|
||||||
"PYTHONLEGACYWINDOWSSTDIO");
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static _PyInitError
|
static _PyInitError
|
||||||
config_init_home(_PyCoreConfig *config)
|
config_init_home(_PyCoreConfig *config)
|
||||||
{
|
{
|
||||||
|
@ -1944,7 +1915,37 @@ config_init_utf8_mode(_PyCoreConfig *config)
|
||||||
static _PyInitError
|
static _PyInitError
|
||||||
config_read_env_vars(_PyCoreConfig *config)
|
config_read_env_vars(_PyCoreConfig *config)
|
||||||
{
|
{
|
||||||
config->allocator = config_get_env_var(config, "PYTHONMALLOC");
|
assert(!config->ignore_environment);
|
||||||
|
|
||||||
|
/* Get environment variables */
|
||||||
|
get_env_flag(config, &config->debug, "PYTHONDEBUG");
|
||||||
|
get_env_flag(config, &config->verbose, "PYTHONVERBOSE");
|
||||||
|
get_env_flag(config, &config->optimization_level, "PYTHONOPTIMIZE");
|
||||||
|
get_env_flag(config, &config->inspect, "PYTHONINSPECT");
|
||||||
|
|
||||||
|
int dont_write_bytecode = 0;
|
||||||
|
get_env_flag(config, &dont_write_bytecode, "PYTHONDONTWRITEBYTECODE");
|
||||||
|
if (dont_write_bytecode) {
|
||||||
|
config->write_bytecode = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int no_user_site_directory = 0;
|
||||||
|
get_env_flag(config, &no_user_site_directory, "PYTHONNOUSERSITE");
|
||||||
|
if (no_user_site_directory) {
|
||||||
|
config->user_site_directory = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
get_env_flag(config, &config->unbuffered_stdio, "PYTHONUNBUFFERED");
|
||||||
|
#ifdef MS_WINDOWS
|
||||||
|
get_env_flag(config, &config->legacy_windows_fs_encoding,
|
||||||
|
"PYTHONLEGACYWINDOWSFSENCODING");
|
||||||
|
get_env_flag(config, &config->legacy_windows_stdio,
|
||||||
|
"PYTHONLEGACYWINDOWSSTDIO");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (config->allocator == NULL) {
|
||||||
|
config->allocator = config_get_env_var(config, "PYTHONMALLOC");
|
||||||
|
}
|
||||||
|
|
||||||
if (config_get_env_var(config, "PYTHONDUMPREFS")) {
|
if (config_get_env_var(config, "PYTHONDUMPREFS")) {
|
||||||
config->dump_refs = 1;
|
config->dump_refs = 1;
|
||||||
|
@ -1998,8 +1999,6 @@ config_read_complex_options(_PyCoreConfig *config)
|
||||||
config_get_env_var(config, "PYTHONDEVMODE"))
|
config_get_env_var(config, "PYTHONDEVMODE"))
|
||||||
{
|
{
|
||||||
config->dev_mode = 1;
|
config->dev_mode = 1;
|
||||||
config->faulthandler = 1;
|
|
||||||
config->allocator = "debug";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_PyInitError err = pymain_init_tracemalloc(config);
|
_PyInitError err = pymain_init_tracemalloc(config);
|
||||||
|
@ -2033,25 +2032,19 @@ pymain_read_conf_impl(_PyMain *pymain, _PyCoreConfig *config,
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get environment variables */
|
|
||||||
cmdline_get_env_flags(pymain, config, cmdline);
|
|
||||||
|
|
||||||
err = cmdline_init_env_warnoptions(pymain, config, cmdline);
|
|
||||||
if (_Py_INIT_FAILED(err)) {
|
|
||||||
pymain->err = err;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef MS_WINDOWS
|
|
||||||
if (config->legacy_windows_fs_encoding) {
|
|
||||||
config->utf8_mode = 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (pymain_init_core_argv(pymain, config, cmdline) < 0) {
|
if (pymain_init_core_argv(pymain, config, cmdline) < 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
assert(config->ignore_environment >= 0);
|
||||||
|
if (!config->ignore_environment) {
|
||||||
|
err = cmdline_init_env_warnoptions(pymain, config, cmdline);
|
||||||
|
if (_Py_INIT_FAILED(err)) {
|
||||||
|
pymain->err = err;
|
||||||
|
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;
|
||||||
|
@ -2186,14 +2179,6 @@ config_init_locale(_PyCoreConfig *config)
|
||||||
}
|
}
|
||||||
return;
|
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -2216,9 +2201,12 @@ _PyCoreConfig_Read(_PyCoreConfig *config)
|
||||||
|
|
||||||
_PyCoreConfig_GetGlobalConfig(config);
|
_PyCoreConfig_GetGlobalConfig(config);
|
||||||
|
|
||||||
err = config_read_env_vars(config);
|
assert(config->ignore_environment >= 0);
|
||||||
if (_Py_INIT_FAILED(err)) {
|
if (!config->ignore_environment) {
|
||||||
return err;
|
err = config_read_env_vars(config);
|
||||||
|
if (_Py_INIT_FAILED(err)) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -X options */
|
/* -X options */
|
||||||
|
@ -2260,13 +2248,38 @@ _PyCoreConfig_Read(_PyCoreConfig *config)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* options side effects */
|
||||||
|
if (config->dev_mode) {
|
||||||
|
if (config->faulthandler < 0) {
|
||||||
|
config->faulthandler = 1;
|
||||||
|
}
|
||||||
|
if (config->allocator == NULL) {
|
||||||
|
config->allocator = "debug";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef MS_WINDOWS
|
||||||
|
if (config->legacy_windows_fs_encoding) {
|
||||||
|
config->utf8_mode = 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* default values */
|
/* default values */
|
||||||
|
if (config->use_hash_seed < 0) {
|
||||||
|
config->use_hash_seed = 0;
|
||||||
|
config->hash_seed = 0;
|
||||||
|
}
|
||||||
|
if (config->faulthandler < 0) {
|
||||||
|
config->faulthandler = 0;
|
||||||
|
}
|
||||||
if (config->tracemalloc < 0) {
|
if (config->tracemalloc < 0) {
|
||||||
config->tracemalloc = 0;
|
config->tracemalloc = 0;
|
||||||
}
|
}
|
||||||
if (config->install_signal_handlers < 0) {
|
if (config->coerce_c_locale < 0) {
|
||||||
/* Signal handlers are installed by default */
|
config->coerce_c_locale = 0;
|
||||||
config->install_signal_handlers = 1;
|
}
|
||||||
|
if (config->utf8_mode < 0) {
|
||||||
|
config->utf8_mode = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return _Py_INIT_OK();
|
return _Py_INIT_OK();
|
||||||
|
@ -2599,7 +2612,6 @@ pymain_init(_PyMain *pymain, PyInterpreterState **interp_p)
|
||||||
|
|
||||||
_PyCoreConfig local_config = _PyCoreConfig_INIT;
|
_PyCoreConfig local_config = _PyCoreConfig_INIT;
|
||||||
_PyCoreConfig *config = &local_config;
|
_PyCoreConfig *config = &local_config;
|
||||||
config->install_signal_handlers = 1;
|
|
||||||
|
|
||||||
_PyCoreConfig_GetGlobalConfig(config);
|
_PyCoreConfig_GetGlobalConfig(config);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue