Set by -X utf8 command line option and PYTHONUTF8 environment variable.
If set to -1 (default), inherit Py_UTF8Mode value. */
int utf8_mode;
+
+ int dev_mode; /* Development mode. PYTHONDEVMODE, -X dev */
+ char *allocator; /* Memory allocator: PYTHONMALLOC */
} _PyPreConfig;
#ifdef MS_WINDOWS
int use_hash_seed; /* PYTHONHASHSEED=x */
unsigned long hash_seed;
- const char *allocator; /* Memory allocator: PYTHONMALLOC */
- int dev_mode; /* PYTHONDEVMODE, -X dev */
-
/* Enable faulthandler?
Set to 1 by -X faulthandler and PYTHONFAULTHANDLER. -1 means unset. */
int faulthandler;
}
self.check_config("init_from_config", config)
+ INIT_ENV_CONFIG = {
+ 'use_hash_seed': 1,
+ 'hash_seed': 42,
+ 'allocator': 'malloc_debug',
+ 'tracemalloc': 2,
+ 'import_time': 1,
+ 'malloc_stats': 1,
+ 'utf8_mode': 1,
+ 'filesystem_encoding': 'utf-8',
+ 'filesystem_errors': UTF8_MODE_ERRORS,
+ 'inspect': 1,
+ 'optimization_level': 2,
+ 'pycache_prefix': 'env_pycache_prefix',
+ 'write_bytecode': 0,
+ 'verbose': 1,
+ 'buffered_stdio': 0,
+ 'stdio_encoding': 'iso8859-1',
+ 'stdio_errors': 'replace',
+ 'user_site_directory': 0,
+ 'faulthandler': 1,
+ }
+
def test_init_env(self):
- config = {
- 'use_hash_seed': 1,
- 'hash_seed': 42,
- 'allocator': 'malloc_debug',
- 'tracemalloc': 2,
- 'import_time': 1,
- 'malloc_stats': 1,
- 'utf8_mode': 1,
- 'filesystem_encoding': 'utf-8',
- 'filesystem_errors': self.UTF8_MODE_ERRORS,
- 'inspect': 1,
- 'optimization_level': 2,
- 'pycache_prefix': 'env_pycache_prefix',
- 'write_bytecode': 0,
- 'verbose': 1,
- 'buffered_stdio': 0,
- 'stdio_encoding': 'iso8859-1',
- 'stdio_errors': 'replace',
- 'user_site_directory': 0,
- 'faulthandler': 1,
- 'dev_mode': 1,
- }
- self.check_config("init_env", config)
+ self.check_config("init_env", self.INIT_ENV_CONFIG)
+
+ def test_init_env_dev_mode(self):
+ config = dict(self.INIT_ENV_CONFIG,
+ allocator='debug',
+ dev_mode=1)
+ self.check_config("init_env_dev_mode", config)
def test_init_dev_mode(self):
config = {
config.hash_seed = 123;
putenv("PYTHONMALLOC=malloc");
- config.allocator = "malloc_debug";
+ config.preconfig.allocator = "malloc_debug";
/* dev_mode=1 is tested in test_init_dev_mode() */
putenv("PYTHONPYCACHEPREFIX=env_pycache_prefix");
putenv("PYTHONNOUSERSITE=1");
putenv("PYTHONFAULTHANDLER=1");
- putenv("PYTHONDEVMODE=1");
putenv("PYTHONIOENCODING=iso8859-1:replace");
/* FIXME: test PYTHONWARNINGS */
/* FIXME: test PYTHONEXECUTABLE */
}
+static void test_init_env_dev_mode_putenvs(void)
+{
+ test_init_env_putenvs();
+ putenv("PYTHONMALLOC=malloc");
+ putenv("PYTHONFAULTHANDLER=");
+ putenv("PYTHONDEVMODE=1");
+}
+
+
static int test_init_env(void)
{
/* Test initialization from environment variables */
}
+static int test_init_env_dev_mode(void)
+{
+ /* Test initialization from environment variables */
+ Py_IgnoreEnvironmentFlag = 0;
+ test_init_env_dev_mode_putenvs();
+ _testembed_Py_Initialize();
+ dump_config();
+ Py_Finalize();
+ return 0;
+}
+
+
static int test_init_isolated(void)
{
/* Test _PyCoreConfig.isolated=1 */
/* Use path starting with "./" avoids a search along the PATH */
config.program_name = L"./_testembed";
- test_init_env_putenvs();
+ test_init_env_dev_mode_putenvs();
_PyInitError err = _Py_InitializeFromConfig(&config);
if (_Py_INIT_FAILED(err)) {
_Py_ExitInitError(err);
_PyCoreConfig config = _PyCoreConfig_INIT;
putenv("PYTHONFAULTHANDLER=");
putenv("PYTHONMALLOC=");
- config.dev_mode = 1;
+ config.preconfig.dev_mode = 1;
config.program_name = L"./_testembed";
_PyInitError err = _Py_InitializeFromConfig(&config);
if (_Py_INIT_FAILED(err)) {
{ "init_global_config", test_init_global_config },
{ "init_from_config", test_init_from_config },
{ "init_env", test_init_env },
+ { "init_env_dev_mode", test_init_env_dev_mode },
{ "init_dev_mode", test_init_dev_mode },
{ "init_isolated", test_init_isolated },
{ NULL, NULL }
COPY_ATTR(use_hash_seed);
COPY_ATTR(hash_seed);
COPY_ATTR(_install_importlib);
- COPY_ATTR(allocator);
- COPY_ATTR(dev_mode);
COPY_ATTR(faulthandler);
COPY_ATTR(tracemalloc);
COPY_ATTR(import_time);
"PYTHONLEGACYWINDOWSSTDIO");
#endif
- if (config->allocator == NULL) {
- config->allocator = _PyCoreConfig_GetEnv(config, "PYTHONMALLOC");
- }
-
if (_PyCoreConfig_GetEnv(config, "PYTHONDUMPREFS")) {
config->dump_refs = 1;
}
|| config_get_xoption(config, L"importtime")) {
config->import_time = 1;
}
- if (config_get_xoption(config, L"dev" ) ||
- _PyCoreConfig_GetEnv(config, "PYTHONDEVMODE"))
- {
- config->dev_mode = 1;
- }
_PyInitError err;
if (config->tracemalloc < 0) {
}
/* default values */
- if (config->dev_mode) {
+ if (config->preconfig.dev_mode) {
if (config->faulthandler < 0) {
config->faulthandler = 1;
}
- if (config->allocator == NULL) {
- config->allocator = "debug";
- }
}
if (config->use_hash_seed < 0) {
config->use_hash_seed = 0;
SET_ITEM_INT(install_signal_handlers);
SET_ITEM_INT(use_hash_seed);
SET_ITEM_UINT(hash_seed);
- SET_ITEM_STR(allocator);
- SET_ITEM_INT(dev_mode);
SET_ITEM_INT(faulthandler);
SET_ITEM_INT(tracemalloc);
SET_ITEM_INT(import_time);
* the lowest precedence entries first so that later entries override them.
*/
- if (config->dev_mode) {
+ if (config->preconfig.dev_mode) {
err = _Py_wstrlist_append(&config->nwarnoption,
&config->warnoptions,
L"default");
void
_PyPreConfig_Clear(_PyPreConfig *config)
{
+#define CLEAR(ATTR) \
+ do { \
+ PyMem_RawFree(ATTR); \
+ ATTR = NULL; \
+ } while (0)
+
+ CLEAR(config->allocator);
+
+#undef CLEAR
}
_PyPreConfig_Clear(config);
#define COPY_ATTR(ATTR) config->ATTR = config2->ATTR
+#define COPY_STR_ATTR(ATTR) \
+ do { \
+ if (config2->ATTR != NULL) { \
+ config->ATTR = _PyMem_RawStrdup(config2->ATTR); \
+ if (config->ATTR == NULL) { \
+ return -1; \
+ } \
+ } \
+ } while (0)
COPY_ATTR(isolated);
COPY_ATTR(use_environment);
COPY_ATTR(legacy_windows_fs_encoding);
#endif
COPY_ATTR(utf8_mode);
+ COPY_ATTR(dev_mode);
+ COPY_STR_ATTR(allocator);
#undef COPY_ATTR
+#undef COPY_STR_ATTR
return 0;
}
{
_PyPreConfig_GetGlobalConfig(config);
+ /* isolated and use_environment */
if (config->isolated > 0) {
config->use_environment = 0;
}
config->use_environment = 0;
}
+ /* legacy_windows_fs_encoding, utf8_mode, coerce_c_locale */
if (config->use_environment) {
#ifdef MS_WINDOWS
_Py_get_env_flag(config, &config->legacy_windows_fs_encoding,
if (config->utf8_mode < 0) {
config->utf8_mode = 0;
}
+ if (config->coerce_c_locale < 0) {
+ config->coerce_c_locale = 0;
+ }
+
+ /* dev_mode */
+ if ((cmdline && _Py_get_xoption(cmdline->nxoption, cmdline->xoptions, L"dev"))
+ || _PyPreConfig_GetEnv(config, "PYTHONDEVMODE"))
+ {
+ config->dev_mode = 1;
+ }
+ if (config->dev_mode < 0) {
+ config->dev_mode = 0;
+ }
+
+ /* allocator */
+ if (config->dev_mode && config->allocator == NULL) {
+ config->allocator = _PyMem_RawStrdup("debug");
+ if (config->allocator == NULL) {
+ return _Py_INIT_NO_MEMORY();
+ }
+ }
+
+ if (config->allocator == NULL) {
+ const char *allocator = _PyPreConfig_GetEnv(config, "PYTHONMALLOC");
+ if (allocator) {
+ config->allocator = _PyMem_RawStrdup(allocator);
+ if (config->allocator == NULL) {
+ return _Py_INIT_NO_MEMORY();
+ }
+ }
+ }
assert(config->coerce_c_locale >= 0);
assert(config->utf8_mode >= 0);
assert(config->isolated >= 0);
assert(config->use_environment >= 0);
+ assert(config->dev_mode >= 0);
return _Py_INIT_OK();
}
} while (0)
#define SET_ITEM_INT(ATTR) \
SET_ITEM(#ATTR, PyLong_FromLong(config->ATTR))
+#define FROM_STRING(STR) \
+ ((STR != NULL) ? \
+ PyUnicode_FromString(STR) \
+ : (Py_INCREF(Py_None), Py_None))
+#define SET_ITEM_STR(ATTR) \
+ SET_ITEM(#ATTR, FROM_STRING(config->ATTR))
SET_ITEM_INT(isolated);
SET_ITEM_INT(use_environment);
#ifdef MS_WINDOWS
SET_ITEM_INT(legacy_windows_fs_encoding);
#endif
+ SET_ITEM_INT(dev_mode);
+ SET_ITEM_STR(allocator);
return 0;
fail:
return -1;
+#undef FROM_STRING
#undef SET_ITEM
#undef SET_ITEM_INT
+#undef SET_ITEM_STR
}
/* bpo-34008: For backward compatibility reasons, calling Py_Main() after
Py_Initialize() ignores the new configuration. */
- if (core_config->allocator != NULL) {
+ if (core_config->preconfig.allocator != NULL) {
const char *allocator = _PyMem_GetAllocatorsName();
- if (allocator == NULL || strcmp(core_config->allocator, allocator) != 0) {
+ if (allocator == NULL || strcmp(core_config->preconfig.allocator, allocator) != 0) {
return _Py_INIT_USER_ERR("cannot modify memory allocator "
"after first Py_Initialize()");
}
return err;
}
- if (core_config->allocator != NULL) {
- if (_PyMem_SetupAllocators(core_config->allocator) < 0) {
+ if (core_config->preconfig.allocator != NULL) {
+ if (_PyMem_SetupAllocators(core_config->preconfig.allocator) < 0) {
return _Py_INIT_USER_ERR("Unknown PYTHONMALLOC allocator");
}
}
SetFlag(config->quiet);
SetFlag(config->use_hash_seed == 0 || config->hash_seed != 0);
SetFlag(config->preconfig.isolated);
- PyStructSequence_SET_ITEM(seq, pos++, PyBool_FromLong(config->dev_mode));
+ PyStructSequence_SET_ITEM(seq, pos++, PyBool_FromLong(config->preconfig.dev_mode));
SetFlag(config->preconfig.utf8_mode);
#undef SetFlag