bpo-36763: Add _PyPreConfig._config_init (GH-13481)
* _PyPreConfig_GetGlobalConfig() and _PyCoreConfig_GetGlobalConfig() now do nothing if the configuration was not initialized with _PyPreConfig_InitCompatConfig() and _PyCoreConfig_InitCompatConfig() * Remove utf8_mode=-2 special case: use utf8_mode=-1 instead. * Fix _PyPreConfig_InitPythonConfig(): * isolated = 0 instead of -1 * use_environment = 1 instead of -1 * Rename _PyConfig_INIT to _PyConfig_INIT_COMPAT * Rename _PyPreConfig_Init() to _PyPreConfig_InitCompatConfig() * Rename _PyCoreConfig_Init() to _PyCoreConfig_InitCompatConfig() * PyInterpreterState_New() now uses _PyCoreConfig_InitPythonConfig() as default configuration, but it's very quickly overriden anyway. * _freeze_importlib.c uses _PyCoreConfig_SetString() to set program_name. * Cleanup preconfig_init_utf8_mode(): cmdline is always non-NULL.
This commit is contained in:
parent
e4d300e07c
commit
022be02dcf
|
@ -40,9 +40,18 @@ typedef struct {
|
|||
|
||||
#define _Py_CONFIG_VERSION 1
|
||||
|
||||
typedef enum {
|
||||
/* Py_Initialize() API: backward compatibility with Python 3.6 and 3.7 */
|
||||
_PyConfig_INIT_COMPAT = 1,
|
||||
_PyConfig_INIT_PYTHON = 2,
|
||||
_PyConfig_INIT_ISOLATED = 3
|
||||
} _PyConfigInitEnum;
|
||||
|
||||
|
||||
typedef struct {
|
||||
int _config_version; /* Internal configuration version,
|
||||
used for ABI compatibility */
|
||||
int _config_init; /* _PyConfigInitEnum value */
|
||||
|
||||
/* Parse _Py_PreInitializeFromArgs() arguments?
|
||||
See _PyCoreConfig.parse_argv */
|
||||
|
@ -107,10 +116,7 @@ typedef struct {
|
|||
Set to 0 by "-X utf8=0" and PYTHONUTF8=0.
|
||||
|
||||
If equals to -1, it is set to 1 if the LC_CTYPE locale is "C" or
|
||||
"POSIX", otherwise it is set to 0.
|
||||
|
||||
If equals to -2, inherit Py_UTF8Mode value value (which is equal to 0
|
||||
by default). */
|
||||
"POSIX", otherwise it is set to 0. Inherit Py_UTF8Mode value value. */
|
||||
int utf8_mode;
|
||||
|
||||
int dev_mode; /* Development mode. PYTHONDEVMODE, -X dev */
|
||||
|
@ -126,16 +132,10 @@ PyAPI_FUNC(void) _PyPreConfig_InitIsolatedConfig(_PyPreConfig *config);
|
|||
|
||||
/* --- _PyCoreConfig ---------------------------------------------- */
|
||||
|
||||
typedef enum {
|
||||
_PyCoreConfig_INIT = 0,
|
||||
_PyCoreConfig_INIT_PYTHON = 1,
|
||||
_PyCoreConfig_INIT_ISOLATED = 2
|
||||
} _PyCoreConfigInitEnum;
|
||||
|
||||
typedef struct {
|
||||
int _config_version; /* Internal configuration version,
|
||||
used for ABI compatibility */
|
||||
int _config_init; /* _PyCoreConfigInitEnum value */
|
||||
int _config_init; /* _PyConfigInitEnum value */
|
||||
|
||||
int isolated; /* Isolated mode? see _PyPreConfig.isolated */
|
||||
int use_environment; /* Use environment variables? see _PyPreConfig.use_environment */
|
||||
|
|
|
@ -120,7 +120,7 @@ PyAPI_FUNC(_PyInitError) _PyPreCmdline_Read(_PyPreCmdline *cmdline,
|
|||
|
||||
/* --- _PyPreConfig ----------------------------------------------- */
|
||||
|
||||
PyAPI_FUNC(void) _PyPreConfig_Init(_PyPreConfig *config);
|
||||
PyAPI_FUNC(void) _PyPreConfig_InitCompatConfig(_PyPreConfig *config);
|
||||
PyAPI_FUNC(void) _PyPreConfig_InitFromCoreConfig(
|
||||
_PyPreConfig *config,
|
||||
const _PyCoreConfig *coreconfig);
|
||||
|
@ -139,7 +139,7 @@ PyAPI_FUNC(_PyInitError) _PyPreConfig_Write(const _PyPreConfig *config);
|
|||
|
||||
/* --- _PyCoreConfig ---------------------------------------------- */
|
||||
|
||||
PyAPI_FUNC(void) _PyCoreConfig_Init(_PyCoreConfig *config);
|
||||
PyAPI_FUNC(void) _PyCoreConfig_InitCompatConfig(_PyCoreConfig *config);
|
||||
PyAPI_FUNC(_PyInitError) _PyCoreConfig_Copy(
|
||||
_PyCoreConfig *config,
|
||||
const _PyCoreConfig *config2);
|
||||
|
|
|
@ -13,13 +13,17 @@ import textwrap
|
|||
|
||||
|
||||
MS_WINDOWS = (os.name == 'nt')
|
||||
|
||||
PYMEM_ALLOCATOR_NOT_SET = 0
|
||||
PYMEM_ALLOCATOR_DEBUG = 2
|
||||
PYMEM_ALLOCATOR_MALLOC = 3
|
||||
|
||||
CONFIG_INIT = 0
|
||||
CONFIG_INIT_PYTHON = 1
|
||||
CONFIG_INIT_ISOLATED = 2
|
||||
# _PyCoreConfig_InitCompatConfig()
|
||||
API_COMPAT = 1
|
||||
# _PyCoreConfig_InitPythonConfig()
|
||||
API_PYTHON = 2
|
||||
# _PyCoreConfig_InitIsolatedConfig()
|
||||
API_ISOLATED = 3
|
||||
|
||||
|
||||
class EmbeddingTestsMixin:
|
||||
|
@ -282,7 +286,7 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase):
|
|||
# Marker to ignore a configuration parameter
|
||||
IGNORE_CONFIG = object()
|
||||
|
||||
DEFAULT_PRE_CONFIG = {
|
||||
PRE_CONFIG_COMPAT = {
|
||||
'allocator': PYMEM_ALLOCATOR_NOT_SET,
|
||||
'parse_argv': 0,
|
||||
'configure_locale': 1,
|
||||
|
@ -291,15 +295,15 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase):
|
|||
'utf8_mode': 0,
|
||||
}
|
||||
if MS_WINDOWS:
|
||||
DEFAULT_PRE_CONFIG.update({
|
||||
PRE_CONFIG_COMPAT.update({
|
||||
'legacy_windows_fs_encoding': 0,
|
||||
})
|
||||
PYTHON_PRE_CONFIG = dict(DEFAULT_PRE_CONFIG,
|
||||
PRE_CONFIG_PYTHON = dict(PRE_CONFIG_COMPAT,
|
||||
parse_argv=1,
|
||||
coerce_c_locale=GET_DEFAULT_CONFIG,
|
||||
utf8_mode=GET_DEFAULT_CONFIG,
|
||||
)
|
||||
ISOLATED_PRE_CONFIG = dict(DEFAULT_PRE_CONFIG,
|
||||
PRE_CONFIG_ISOLATED = dict(PRE_CONFIG_COMPAT,
|
||||
configure_locale=0,
|
||||
isolated=1,
|
||||
use_environment=0,
|
||||
|
@ -314,8 +318,8 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase):
|
|||
'use_environment',
|
||||
]
|
||||
|
||||
DEFAULT_CORE_CONFIG = {
|
||||
'_config_init': CONFIG_INIT,
|
||||
CORE_CONFIG_COMPAT = {
|
||||
'_config_init': API_COMPAT,
|
||||
'isolated': 0,
|
||||
'use_environment': 1,
|
||||
'dev_mode': 0,
|
||||
|
@ -379,15 +383,15 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase):
|
|||
'_init_main': 1,
|
||||
}
|
||||
if MS_WINDOWS:
|
||||
DEFAULT_CORE_CONFIG.update({
|
||||
CORE_CONFIG_COMPAT.update({
|
||||
'legacy_windows_stdio': 0,
|
||||
})
|
||||
|
||||
PYTHON_CORE_CONFIG = dict(DEFAULT_CORE_CONFIG,
|
||||
CORE_CONFIG_PYTHON = dict(CORE_CONFIG_COMPAT,
|
||||
configure_c_stdio=1,
|
||||
parse_argv=1,
|
||||
)
|
||||
ISOLATED_CORE_CONFIG = dict(DEFAULT_CORE_CONFIG,
|
||||
CORE_CONFIG_ISOLATED = dict(CORE_CONFIG_COMPAT,
|
||||
isolated=1,
|
||||
use_environment=0,
|
||||
user_site_directory=0,
|
||||
|
@ -399,7 +403,7 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase):
|
|||
pathconfig_warnings=0,
|
||||
)
|
||||
if MS_WINDOWS:
|
||||
ISOLATED_CORE_CONFIG['legacy_windows_stdio'] = 0
|
||||
CORE_CONFIG_ISOLATED['legacy_windows_stdio'] = 0
|
||||
|
||||
# global config
|
||||
DEFAULT_GLOBAL_CONFIG = {
|
||||
|
@ -492,7 +496,7 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase):
|
|||
if value is self.GET_DEFAULT_CONFIG:
|
||||
expected_preconfig[key] = pre_config[key]
|
||||
|
||||
if not expected_preconfig['configure_locale'] or api == CONFIG_INIT:
|
||||
if not expected_preconfig['configure_locale'] or api == API_COMPAT:
|
||||
# there is no easy way to get the locale encoding before
|
||||
# setlocale(LC_CTYPE, "") is called: don't test encodings
|
||||
for key in ('filesystem_encoding', 'filesystem_errors',
|
||||
|
@ -579,32 +583,33 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase):
|
|||
|
||||
self.assertEqual(config['global_config'], expected)
|
||||
|
||||
def check_config(self, testname, expected_config=None, expected_preconfig=None,
|
||||
add_path=None, stderr=None, api=CONFIG_INIT):
|
||||
def check_config(self, testname, expected_config=None,
|
||||
expected_preconfig=None, add_path=None, stderr=None,
|
||||
*, api):
|
||||
env = dict(os.environ)
|
||||
# Remove PYTHON* environment variables to get deterministic environment
|
||||
for key in list(env):
|
||||
if key.startswith('PYTHON'):
|
||||
del env[key]
|
||||
|
||||
if api == CONFIG_INIT_ISOLATED:
|
||||
default_preconfig = self.ISOLATED_PRE_CONFIG
|
||||
elif api == CONFIG_INIT_PYTHON:
|
||||
default_preconfig = self.PYTHON_PRE_CONFIG
|
||||
if api == API_ISOLATED:
|
||||
default_preconfig = self.PRE_CONFIG_ISOLATED
|
||||
elif api == API_PYTHON:
|
||||
default_preconfig = self.PRE_CONFIG_PYTHON
|
||||
else:
|
||||
default_preconfig = self.DEFAULT_PRE_CONFIG
|
||||
default_preconfig = self.PRE_CONFIG_COMPAT
|
||||
if expected_preconfig is None:
|
||||
expected_preconfig = {}
|
||||
expected_preconfig = dict(default_preconfig, **expected_preconfig)
|
||||
if expected_config is None:
|
||||
expected_config = {}
|
||||
|
||||
if api == CONFIG_INIT_PYTHON:
|
||||
default_config = self.PYTHON_CORE_CONFIG
|
||||
elif api == CONFIG_INIT_ISOLATED:
|
||||
default_config = self.ISOLATED_CORE_CONFIG
|
||||
if api == API_PYTHON:
|
||||
default_config = self.CORE_CONFIG_PYTHON
|
||||
elif api == API_ISOLATED:
|
||||
default_config = self.CORE_CONFIG_ISOLATED
|
||||
else:
|
||||
default_config = self.DEFAULT_CORE_CONFIG
|
||||
default_config = self.CORE_CONFIG_COMPAT
|
||||
expected_config = dict(default_config, **expected_config)
|
||||
expected_config['_config_init'] = api
|
||||
|
||||
|
@ -627,7 +632,13 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase):
|
|||
self.check_global_config(config)
|
||||
|
||||
def test_init_default_config(self):
|
||||
self.check_config("init_default_config", {}, {})
|
||||
self.check_config("init_initialize_config", api=API_COMPAT)
|
||||
|
||||
def test_preinit_compat_config(self):
|
||||
self.check_config("preinit_compat_config", api=API_COMPAT)
|
||||
|
||||
def test_init_compat_config(self):
|
||||
self.check_config("init_compat_config", api=API_COMPAT)
|
||||
|
||||
def test_init_global_config(self):
|
||||
preconfig = {
|
||||
|
@ -649,7 +660,8 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase):
|
|||
'user_site_directory': 0,
|
||||
'pathconfig_warnings': 0,
|
||||
}
|
||||
self.check_config("init_global_config", config, preconfig)
|
||||
self.check_config("init_global_config", config, preconfig,
|
||||
api=API_COMPAT)
|
||||
|
||||
def test_init_from_config(self):
|
||||
preconfig = {
|
||||
|
@ -693,11 +705,13 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase):
|
|||
'check_hash_pycs_mode': 'always',
|
||||
'pathconfig_warnings': 0,
|
||||
}
|
||||
self.check_config("init_from_config", config, preconfig)
|
||||
self.check_config("init_from_config", config, preconfig,
|
||||
api=API_COMPAT)
|
||||
|
||||
def test_init_env(self):
|
||||
preconfig = {
|
||||
'allocator': PYMEM_ALLOCATOR_MALLOC,
|
||||
'utf8_mode': 1,
|
||||
}
|
||||
config = {
|
||||
'use_hash_seed': 1,
|
||||
|
@ -718,21 +732,24 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase):
|
|||
'faulthandler': 1,
|
||||
'warnoptions': ['EnvVar'],
|
||||
}
|
||||
self.check_config("init_env", config, preconfig)
|
||||
self.check_config("init_env", config, preconfig,
|
||||
api=API_COMPAT)
|
||||
|
||||
def test_init_env_dev_mode(self):
|
||||
preconfig = dict(allocator=PYMEM_ALLOCATOR_DEBUG)
|
||||
config = dict(dev_mode=1,
|
||||
faulthandler=1,
|
||||
warnoptions=['default'])
|
||||
self.check_config("init_env_dev_mode", config, preconfig)
|
||||
self.check_config("init_env_dev_mode", config, preconfig,
|
||||
api=API_COMPAT)
|
||||
|
||||
def test_init_env_dev_mode_alloc(self):
|
||||
preconfig = dict(allocator=PYMEM_ALLOCATOR_MALLOC)
|
||||
config = dict(dev_mode=1,
|
||||
faulthandler=1,
|
||||
warnoptions=['default'])
|
||||
self.check_config("init_env_dev_mode_alloc", config, preconfig)
|
||||
self.check_config("init_env_dev_mode_alloc", config, preconfig,
|
||||
api=API_COMPAT)
|
||||
|
||||
def test_init_dev_mode(self):
|
||||
preconfig = {
|
||||
|
@ -744,7 +761,7 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase):
|
|||
'warnoptions': ['default'],
|
||||
}
|
||||
self.check_config("init_dev_mode", config, preconfig,
|
||||
api=CONFIG_INIT_PYTHON)
|
||||
api=API_PYTHON)
|
||||
|
||||
def test_preinit_parse_argv(self):
|
||||
# Pre-initialize implicitly using argv: make sure that -X dev
|
||||
|
@ -761,7 +778,7 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase):
|
|||
'xoptions': ['dev'],
|
||||
}
|
||||
self.check_config("preinit_parse_argv", config, preconfig,
|
||||
api=CONFIG_INIT_PYTHON)
|
||||
api=API_PYTHON)
|
||||
|
||||
def test_preinit_dont_parse_argv(self):
|
||||
# -X dev must be ignored by isolated preconfiguration
|
||||
|
@ -774,7 +791,7 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase):
|
|||
'isolated': 0,
|
||||
}
|
||||
self.check_config("preinit_dont_parse_argv", config, preconfig,
|
||||
api=CONFIG_INIT_ISOLATED)
|
||||
api=API_ISOLATED)
|
||||
|
||||
def test_init_isolated_flag(self):
|
||||
config = {
|
||||
|
@ -782,7 +799,7 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase):
|
|||
'use_environment': 0,
|
||||
'user_site_directory': 0,
|
||||
}
|
||||
self.check_config("init_isolated_flag", config, api=CONFIG_INIT_PYTHON)
|
||||
self.check_config("init_isolated_flag", config, api=API_PYTHON)
|
||||
|
||||
def test_preinit_isolated1(self):
|
||||
# _PyPreConfig.isolated=1, _PyCoreConfig.isolated not set
|
||||
|
@ -791,7 +808,7 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase):
|
|||
'use_environment': 0,
|
||||
'user_site_directory': 0,
|
||||
}
|
||||
self.check_config("preinit_isolated1", config)
|
||||
self.check_config("preinit_isolated1", config, api=API_COMPAT)
|
||||
|
||||
def test_preinit_isolated2(self):
|
||||
# _PyPreConfig.isolated=0, _PyCoreConfig.isolated=1
|
||||
|
@ -800,16 +817,16 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase):
|
|||
'use_environment': 0,
|
||||
'user_site_directory': 0,
|
||||
}
|
||||
self.check_config("preinit_isolated2", config)
|
||||
self.check_config("preinit_isolated2", config, api=API_COMPAT)
|
||||
|
||||
def test_preinit_isolated_config(self):
|
||||
self.check_config("preinit_isolated_config", api=CONFIG_INIT_ISOLATED)
|
||||
self.check_config("preinit_isolated_config", api=API_ISOLATED)
|
||||
|
||||
def test_init_isolated_config(self):
|
||||
self.check_config("init_isolated_config", api=CONFIG_INIT_ISOLATED)
|
||||
self.check_config("init_isolated_config", api=API_ISOLATED)
|
||||
|
||||
def test_init_python_config(self):
|
||||
self.check_config("init_python_config", api=CONFIG_INIT_PYTHON)
|
||||
self.check_config("init_python_config", api=API_PYTHON)
|
||||
|
||||
def test_init_dont_configure_locale(self):
|
||||
# _PyPreConfig.configure_locale=0
|
||||
|
@ -818,7 +835,7 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase):
|
|||
'coerce_c_locale': 0,
|
||||
}
|
||||
self.check_config("init_dont_configure_locale", {}, preconfig,
|
||||
api=CONFIG_INIT_PYTHON)
|
||||
api=API_PYTHON)
|
||||
|
||||
def test_init_read_set(self):
|
||||
core_config = {
|
||||
|
@ -826,7 +843,7 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase):
|
|||
'executable': 'my_executable',
|
||||
}
|
||||
self.check_config("init_read_set", core_config,
|
||||
api=CONFIG_INIT_PYTHON,
|
||||
api=API_PYTHON,
|
||||
add_path="init_read_set_path")
|
||||
|
||||
def test_init_run_main(self):
|
||||
|
@ -838,8 +855,7 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase):
|
|||
'run_command': code + '\n',
|
||||
'parse_argv': 1,
|
||||
}
|
||||
self.check_config("init_run_main", core_config,
|
||||
api=CONFIG_INIT_PYTHON)
|
||||
self.check_config("init_run_main", core_config, api=API_PYTHON)
|
||||
|
||||
def test_init_main(self):
|
||||
code = ('import _testinternalcapi, json; '
|
||||
|
@ -852,7 +868,7 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase):
|
|||
'_init_main': 0,
|
||||
}
|
||||
self.check_config("init_main", core_config,
|
||||
api=CONFIG_INIT_PYTHON,
|
||||
api=API_PYTHON,
|
||||
stderr="Run Python code before _Py_InitializeMain")
|
||||
|
||||
def test_init_parse_argv(self):
|
||||
|
@ -863,8 +879,7 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase):
|
|||
'run_command': 'pass\n',
|
||||
'use_environment': 0,
|
||||
}
|
||||
self.check_config("init_parse_argv", core_config,
|
||||
api=CONFIG_INIT_PYTHON)
|
||||
self.check_config("init_parse_argv", core_config, api=API_PYTHON)
|
||||
|
||||
def test_init_dont_parse_argv(self):
|
||||
pre_config = {
|
||||
|
@ -876,7 +891,7 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase):
|
|||
'program_name': './argv0',
|
||||
}
|
||||
self.check_config("init_dont_parse_argv", core_config, pre_config,
|
||||
api=CONFIG_INIT_PYTHON)
|
||||
api=API_PYTHON)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
|
|
@ -76,18 +76,30 @@ main(int argc, char *argv[])
|
|||
}
|
||||
text[text_size] = '\0';
|
||||
|
||||
_PyInitError err;
|
||||
_PyCoreConfig config;
|
||||
_PyCoreConfig_InitIsolatedConfig(&config);
|
||||
|
||||
err = _PyCoreConfig_InitIsolatedConfig(&config);
|
||||
if (_PyInitError_Failed(err)) {
|
||||
_PyCoreConfig_Clear(&config);
|
||||
_Py_ExitInitError(err);
|
||||
}
|
||||
|
||||
config.site_import = 0;
|
||||
config.program_name = L"./_freeze_importlib";
|
||||
|
||||
err = _PyCoreConfig_SetString(&config, &config.program_name,
|
||||
L"./_freeze_importlib");
|
||||
if (_PyInitError_Failed(err)) {
|
||||
_PyCoreConfig_Clear(&config);
|
||||
_Py_ExitInitError(err);
|
||||
}
|
||||
|
||||
/* Don't install importlib, since it could execute outdated bytecode. */
|
||||
config._install_importlib = 0;
|
||||
config._init_main = 0;
|
||||
|
||||
_PyInitError err = _Py_InitializeFromConfig(&config);
|
||||
/* No need to call _PyCoreConfig_Clear() since we didn't allocate any
|
||||
memory: program_name is a constant string. */
|
||||
err = _Py_InitializeFromConfig(&config);
|
||||
_PyCoreConfig_Clear(&config);
|
||||
if (_PyInitError_Failed(err)) {
|
||||
_Py_ExitInitError(err);
|
||||
}
|
||||
|
|
|
@ -317,7 +317,7 @@ dump_config(void)
|
|||
}
|
||||
|
||||
|
||||
static int test_init_default_config(void)
|
||||
static int test_init_initialize_config(void)
|
||||
{
|
||||
_testembed_Py_Initialize();
|
||||
dump_config();
|
||||
|
@ -326,6 +326,47 @@ static int test_init_default_config(void)
|
|||
}
|
||||
|
||||
|
||||
static int check_init_compat_config(int preinit)
|
||||
{
|
||||
_PyInitError err;
|
||||
|
||||
if (preinit) {
|
||||
_PyPreConfig preconfig;
|
||||
_PyPreConfig_InitCompatConfig(&preconfig);
|
||||
|
||||
err = _Py_PreInitialize(&preconfig);
|
||||
if (_PyInitError_Failed(err)) {
|
||||
_Py_ExitInitError(err);
|
||||
}
|
||||
}
|
||||
|
||||
_PyCoreConfig config;
|
||||
_PyCoreConfig_InitCompatConfig(&config);
|
||||
config.program_name = L"./_testembed";
|
||||
|
||||
err = _Py_InitializeFromConfig(&config);
|
||||
if (_PyInitError_Failed(err)) {
|
||||
_Py_ExitInitError(err);
|
||||
}
|
||||
|
||||
dump_config();
|
||||
Py_Finalize();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int test_preinit_compat_config(void)
|
||||
{
|
||||
return check_init_compat_config(1);
|
||||
}
|
||||
|
||||
|
||||
static int test_init_compat_config(void)
|
||||
{
|
||||
return check_init_compat_config(0);
|
||||
}
|
||||
|
||||
|
||||
static int test_init_global_config(void)
|
||||
{
|
||||
/* FIXME: test Py_IgnoreEnvironmentFlag */
|
||||
|
@ -380,7 +421,7 @@ static int test_init_from_config(void)
|
|||
_PyInitError err;
|
||||
|
||||
_PyPreConfig preconfig;
|
||||
_PyPreConfig_Init(&preconfig);
|
||||
_PyPreConfig_InitCompatConfig(&preconfig);
|
||||
|
||||
putenv("PYTHONMALLOC=malloc_debug");
|
||||
preconfig.allocator = PYMEM_ALLOCATOR_MALLOC;
|
||||
|
@ -396,7 +437,7 @@ static int test_init_from_config(void)
|
|||
|
||||
/* Test _Py_InitializeFromConfig() */
|
||||
_PyCoreConfig config;
|
||||
_PyCoreConfig_Init(&config);
|
||||
_PyCoreConfig_InitCompatConfig(&config);
|
||||
config.install_signal_handlers = 0;
|
||||
|
||||
/* FIXME: test use_environment */
|
||||
|
@ -676,7 +717,7 @@ static int test_preinit_isolated1(void)
|
|||
_PyInitError err;
|
||||
|
||||
_PyPreConfig preconfig;
|
||||
_PyPreConfig_Init(&preconfig);
|
||||
_PyPreConfig_InitCompatConfig(&preconfig);
|
||||
preconfig.isolated = 1;
|
||||
|
||||
err = _Py_PreInitialize(&preconfig);
|
||||
|
@ -685,7 +726,7 @@ static int test_preinit_isolated1(void)
|
|||
}
|
||||
|
||||
_PyCoreConfig config;
|
||||
_PyCoreConfig_Init(&config);
|
||||
_PyCoreConfig_InitCompatConfig(&config);
|
||||
config.program_name = L"./_testembed";
|
||||
|
||||
set_all_env_vars();
|
||||
|
@ -705,7 +746,7 @@ static int test_preinit_isolated2(void)
|
|||
_PyInitError err;
|
||||
|
||||
_PyPreConfig preconfig;
|
||||
_PyPreConfig_Init(&preconfig);
|
||||
_PyPreConfig_InitCompatConfig(&preconfig);
|
||||
preconfig.isolated = 0;
|
||||
|
||||
err = _Py_PreInitialize(&preconfig);
|
||||
|
@ -715,7 +756,7 @@ static int test_preinit_isolated2(void)
|
|||
|
||||
/* Test _PyCoreConfig.isolated=1 */
|
||||
_PyCoreConfig config;
|
||||
_PyCoreConfig_Init(&config);
|
||||
_PyCoreConfig_InitCompatConfig(&config);
|
||||
|
||||
Py_IsolatedFlag = 0;
|
||||
config.isolated = 1;
|
||||
|
@ -885,12 +926,14 @@ static int check_preinit_isolated_config(int preinit)
|
|||
_PyCoreConfig config;
|
||||
err = _PyCoreConfig_InitIsolatedConfig(&config);
|
||||
if (_PyInitError_Failed(err)) {
|
||||
_PyCoreConfig_Clear(&config);
|
||||
_Py_ExitInitError(err);
|
||||
}
|
||||
config.program_name = L"./_testembed";
|
||||
|
||||
err = _Py_InitializeFromConfig(&config);
|
||||
if (_PyInitError_Failed(err)) {
|
||||
_PyCoreConfig_Clear(&config);
|
||||
_Py_ExitInitError(err);
|
||||
}
|
||||
|
||||
|
@ -1207,7 +1250,9 @@ static struct TestCase TestCases[] = {
|
|||
{ "bpo20891", test_bpo20891 },
|
||||
{ "initialize_twice", test_initialize_twice },
|
||||
{ "initialize_pymain", test_initialize_pymain },
|
||||
{ "init_default_config", test_init_default_config },
|
||||
{ "init_initialize_config", test_init_initialize_config },
|
||||
{ "preinit_compat_config", test_preinit_compat_config },
|
||||
{ "init_compat_config", test_init_compat_config },
|
||||
{ "init_global_config", test_init_global_config },
|
||||
{ "init_from_config", test_init_from_config },
|
||||
{ "init_parse_argv", test_init_parse_argv },
|
||||
|
|
|
@ -109,7 +109,7 @@ static const char usage_6[] =
|
|||
/* UTF-8 mode (PEP 540): if equals to 1, use the UTF-8 encoding, and change
|
||||
stdin and stdout error handler to "surrogateescape". It is equal to
|
||||
-1 by default: unknown, will be set by Py_Main() */
|
||||
int Py_UTF8Mode = 0;
|
||||
int Py_UTF8Mode = -1;
|
||||
int Py_DebugFlag = 0; /* Needed by parser.c */
|
||||
int Py_VerboseFlag = 0; /* Needed by import.c */
|
||||
int Py_QuietFlag = 0; /* Needed by sysmodule.c */
|
||||
|
@ -546,12 +546,12 @@ _PyCoreConfig_Clear(_PyCoreConfig *config)
|
|||
|
||||
|
||||
void
|
||||
_PyCoreConfig_Init(_PyCoreConfig *config)
|
||||
_PyCoreConfig_InitCompatConfig(_PyCoreConfig *config)
|
||||
{
|
||||
memset(config, 0, sizeof(*config));
|
||||
|
||||
config->_config_version = _Py_CONFIG_VERSION;
|
||||
config->_config_init = (int)_PyCoreConfig_INIT;
|
||||
config->_config_init = (int)_PyConfig_INIT_COMPAT;
|
||||
config->isolated = -1;
|
||||
config->use_environment = -1;
|
||||
config->dev_mode = -1;
|
||||
|
@ -586,7 +586,7 @@ _PyCoreConfig_Init(_PyCoreConfig *config)
|
|||
static void
|
||||
_PyCoreConfig_InitDefaults(_PyCoreConfig *config)
|
||||
{
|
||||
_PyCoreConfig_Init(config);
|
||||
_PyCoreConfig_InitCompatConfig(config);
|
||||
|
||||
config->isolated = 0;
|
||||
config->use_environment = 1;
|
||||
|
@ -613,7 +613,7 @@ _PyCoreConfig_InitPythonConfig(_PyCoreConfig *config)
|
|||
{
|
||||
_PyCoreConfig_InitDefaults(config);
|
||||
|
||||
config->_config_init = (int)_PyCoreConfig_INIT_PYTHON;
|
||||
config->_config_init = (int)_PyConfig_INIT_PYTHON;
|
||||
config->configure_c_stdio = 1;
|
||||
config->parse_argv = 1;
|
||||
|
||||
|
@ -626,7 +626,7 @@ _PyCoreConfig_InitIsolatedConfig(_PyCoreConfig *config)
|
|||
{
|
||||
_PyCoreConfig_InitDefaults(config);
|
||||
|
||||
config->_config_init = (int)_PyCoreConfig_INIT_ISOLATED;
|
||||
config->_config_init = (int)_PyConfig_INIT_ISOLATED;
|
||||
config->isolated = 1;
|
||||
config->use_environment = 0;
|
||||
config->user_site_directory = 0;
|
||||
|
@ -962,6 +962,11 @@ _PyCoreConfig_GetEnvDup(_PyCoreConfig *config,
|
|||
static void
|
||||
_PyCoreConfig_GetGlobalConfig(_PyCoreConfig *config)
|
||||
{
|
||||
if (config->_config_init != _PyConfig_INIT_COMPAT) {
|
||||
/* Python and Isolated configuration ignore global variables */
|
||||
return;
|
||||
}
|
||||
|
||||
#define COPY_FLAG(ATTR, VALUE) \
|
||||
if (config->ATTR == -1) { \
|
||||
config->ATTR = VALUE; \
|
||||
|
|
|
@ -40,7 +40,11 @@ Py_FrozenMain(int argc, char **argv)
|
|||
}
|
||||
|
||||
_PyCoreConfig config;
|
||||
_PyCoreConfig_InitPythonConfig(&config);
|
||||
err = _PyCoreConfig_InitPythonConfig(&config);
|
||||
if (_PyInitError_Failed(err)) {
|
||||
_PyCoreConfig_Clear(&config);
|
||||
_Py_ExitInitError(err);
|
||||
}
|
||||
config.pathconfig_warnings = 0; /* Suppress errors from getpath.c */
|
||||
|
||||
if ((p = Py_GETENV("PYTHONINSPECT")) && *p != '\0')
|
||||
|
@ -82,8 +86,7 @@ Py_FrozenMain(int argc, char **argv)
|
|||
Py_SetProgramName(argv_copy[0]);
|
||||
|
||||
err = _Py_InitializeFromConfig(&config);
|
||||
/* No need to call _PyCoreConfig_Clear() since we didn't allocate any
|
||||
memory: program_name is a constant string. */
|
||||
_PyCoreConfig_Clear(&config);
|
||||
if (_PyInitError_Failed(err)) {
|
||||
_Py_ExitInitError(err);
|
||||
}
|
||||
|
|
|
@ -383,7 +383,7 @@ pathconfig_global_init(void)
|
|||
|
||||
_PyInitError err;
|
||||
_PyCoreConfig config;
|
||||
_PyCoreConfig_Init(&config);
|
||||
_PyCoreConfig_InitCompatConfig(&config);
|
||||
|
||||
err = _PyCoreConfig_Read(&config);
|
||||
if (_Py_INIT_FAILED(err)) {
|
||||
|
|
|
@ -262,16 +262,17 @@ _PyPreCmdline_Read(_PyPreCmdline *cmdline, const _PyPreConfig *preconfig)
|
|||
|
||||
|
||||
void
|
||||
_PyPreConfig_Init(_PyPreConfig *config)
|
||||
_PyPreConfig_InitCompatConfig(_PyPreConfig *config)
|
||||
{
|
||||
memset(config, 0, sizeof(*config));
|
||||
|
||||
config->_config_version = _Py_CONFIG_VERSION;
|
||||
config->_config_init = (int)_PyConfig_INIT_COMPAT;
|
||||
config->parse_argv = 0;
|
||||
config->isolated = -1;
|
||||
config->use_environment = -1;
|
||||
config->configure_locale = 1;
|
||||
config->utf8_mode = -2;
|
||||
config->utf8_mode = -1;
|
||||
config->dev_mode = -1;
|
||||
config->allocator = PYMEM_ALLOCATOR_NOT_SET;
|
||||
#ifdef MS_WINDOWS
|
||||
|
@ -283,23 +284,30 @@ _PyPreConfig_Init(_PyPreConfig *config)
|
|||
void
|
||||
_PyPreConfig_InitPythonConfig(_PyPreConfig *config)
|
||||
{
|
||||
_PyPreConfig_Init(config);
|
||||
_PyPreConfig_InitCompatConfig(config);
|
||||
|
||||
config->_config_init = (int)_PyConfig_INIT_PYTHON;
|
||||
config->isolated = 0;
|
||||
config->parse_argv = 1;
|
||||
config->use_environment = 1;
|
||||
/* Set to -1 to enable C locale coercion (PEP 538) and UTF-8 Mode (PEP 540)
|
||||
depending on the LC_CTYPE locale, PYTHONUTF8 and PYTHONCOERCECLOCALE
|
||||
environment variables. */
|
||||
config->coerce_c_locale = -1;
|
||||
config->coerce_c_locale_warn = -1;
|
||||
config->utf8_mode = -1;
|
||||
#ifdef MS_WINDOWS
|
||||
config->legacy_windows_fs_encoding = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
_PyPreConfig_InitIsolatedConfig(_PyPreConfig *config)
|
||||
{
|
||||
_PyPreConfig_Init(config);
|
||||
_PyPreConfig_InitCompatConfig(config);
|
||||
|
||||
config->_config_init = (int)_PyConfig_INIT_ISOLATED;
|
||||
config->configure_locale = 0;
|
||||
config->isolated = 1;
|
||||
config->use_environment = 0;
|
||||
|
@ -315,7 +323,7 @@ void
|
|||
_PyPreConfig_InitFromPreConfig(_PyPreConfig *config,
|
||||
const _PyPreConfig *config2)
|
||||
{
|
||||
_PyPreConfig_Init(config);
|
||||
_PyPreConfig_InitCompatConfig(config);
|
||||
_PyPreConfig_Copy(config, config2);
|
||||
}
|
||||
|
||||
|
@ -324,17 +332,17 @@ void
|
|||
_PyPreConfig_InitFromCoreConfig(_PyPreConfig *config,
|
||||
const _PyCoreConfig *coreconfig)
|
||||
{
|
||||
_PyCoreConfigInitEnum config_init = (_PyCoreConfigInitEnum)coreconfig->_config_init;
|
||||
_PyConfigInitEnum config_init = (_PyConfigInitEnum)coreconfig->_config_init;
|
||||
switch (config_init) {
|
||||
case _PyCoreConfig_INIT_PYTHON:
|
||||
case _PyConfig_INIT_PYTHON:
|
||||
_PyPreConfig_InitPythonConfig(config);
|
||||
break;
|
||||
case _PyCoreConfig_INIT_ISOLATED:
|
||||
case _PyConfig_INIT_ISOLATED:
|
||||
_PyPreConfig_InitIsolatedConfig(config);
|
||||
break;
|
||||
case _PyCoreConfig_INIT:
|
||||
case _PyConfig_INIT_COMPAT:
|
||||
default:
|
||||
_PyPreConfig_Init(config);
|
||||
_PyPreConfig_InitCompatConfig(config);
|
||||
}
|
||||
_PyPreConfig_GetCoreConfig(config, coreconfig);
|
||||
}
|
||||
|
@ -428,6 +436,11 @@ _PyPreConfig_GetCoreConfig(_PyPreConfig *config,
|
|||
static void
|
||||
_PyPreConfig_GetGlobalConfig(_PyPreConfig *config)
|
||||
{
|
||||
if (config->_config_init != _PyConfig_INIT_COMPAT) {
|
||||
/* Python and Isolated configuration ignore global variables */
|
||||
return;
|
||||
}
|
||||
|
||||
#define COPY_FLAG(ATTR, VALUE) \
|
||||
if (config->ATTR < 0) { \
|
||||
config->ATTR = VALUE; \
|
||||
|
@ -439,12 +452,10 @@ _PyPreConfig_GetGlobalConfig(_PyPreConfig *config)
|
|||
|
||||
COPY_FLAG(isolated, Py_IsolatedFlag);
|
||||
COPY_NOT_FLAG(use_environment, Py_IgnoreEnvironmentFlag);
|
||||
COPY_FLAG(utf8_mode, Py_UTF8Mode);
|
||||
#ifdef MS_WINDOWS
|
||||
COPY_FLAG(legacy_windows_fs_encoding, Py_LegacyWindowsFSEncodingFlag);
|
||||
#endif
|
||||
if (config->utf8_mode == -2) {
|
||||
config->utf8_mode = Py_UTF8Mode;
|
||||
}
|
||||
|
||||
#undef COPY_FLAG
|
||||
#undef COPY_NOT_FLAG
|
||||
|
@ -565,12 +576,7 @@ preconfig_init_utf8_mode(_PyPreConfig *config, const _PyPreCmdline *cmdline)
|
|||
}
|
||||
|
||||
const wchar_t *xopt;
|
||||
if (cmdline) {
|
||||
xopt = _Py_get_xoption(&cmdline->xoptions, L"utf8");
|
||||
}
|
||||
else {
|
||||
xopt = NULL;
|
||||
}
|
||||
xopt = _Py_get_xoption(&cmdline->xoptions, L"utf8");
|
||||
if (xopt) {
|
||||
wchar_t *sep = wcschr(xopt, L'=');
|
||||
if (sep) {
|
||||
|
|
|
@ -867,7 +867,7 @@ _Py_InitializeCore(_PyRuntimeState *runtime,
|
|||
}
|
||||
|
||||
_PyCoreConfig local_config;
|
||||
_PyCoreConfig_Init(&local_config);
|
||||
_PyCoreConfig_InitCompatConfig(&local_config);
|
||||
err = pyinit_coreconfig(runtime, &local_config, src_config, args, interp_p);
|
||||
_PyCoreConfig_Clear(&local_config);
|
||||
return err;
|
||||
|
@ -1096,7 +1096,7 @@ Py_InitializeEx(int install_sigs)
|
|||
}
|
||||
|
||||
_PyCoreConfig config;
|
||||
_PyCoreConfig_Init(&config);
|
||||
_PyCoreConfig_InitCompatConfig(&config);
|
||||
config.install_signal_handlers = install_sigs;
|
||||
|
||||
err = _Py_InitializeFromConfig(&config);
|
||||
|
|
|
@ -49,7 +49,7 @@ _PyRuntimeState_Init_impl(_PyRuntimeState *runtime)
|
|||
|
||||
_PyGC_Initialize(&runtime->gc);
|
||||
_PyEval_Initialize(&runtime->ceval);
|
||||
_PyPreConfig_Init(&runtime->preconfig);
|
||||
_PyPreConfig_InitPythonConfig(&runtime->preconfig);
|
||||
|
||||
runtime->gilstate.check_enabled = 1;
|
||||
|
||||
|
@ -189,7 +189,13 @@ PyInterpreterState_New(void)
|
|||
memset(interp, 0, sizeof(*interp));
|
||||
interp->id_refcount = -1;
|
||||
interp->check_interval = 100;
|
||||
_PyCoreConfig_Init(&interp->core_config);
|
||||
|
||||
_PyInitError err = _PyCoreConfig_InitPythonConfig(&interp->core_config);
|
||||
if (_Py_INIT_FAILED(err)) {
|
||||
PyMem_RawFree(interp);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
interp->eval_frame = _PyEval_EvalFrameDefault;
|
||||
#ifdef HAVE_DLOPEN
|
||||
#if HAVE_DECL_RTLD_NOW
|
||||
|
|
Loading…
Reference in New Issue