bpo-36763: Add _PyPreConfig._config_init (GH-13481) · python/cpython@022be02
@@ -13,13 +13,17 @@
131314141515MS_WINDOWS = (os.name == 'nt')
16+1617PYMEM_ALLOCATOR_NOT_SET = 0
1718PYMEM_ALLOCATOR_DEBUG = 2
1819PYMEM_ALLOCATOR_MALLOC = 3
192020-CONFIG_INIT = 0
21-CONFIG_INIT_PYTHON = 1
22-CONFIG_INIT_ISOLATED = 2
21+# _PyCoreConfig_InitCompatConfig()
22+API_COMPAT = 1
23+# _PyCoreConfig_InitPythonConfig()
24+API_PYTHON = 2
25+# _PyCoreConfig_InitIsolatedConfig()
26+API_ISOLATED = 3
232724282529class EmbeddingTestsMixin:
@@ -282,7 +286,7 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase):
282286# Marker to ignore a configuration parameter
283287IGNORE_CONFIG = object()
284288285-DEFAULT_PRE_CONFIG = {
289+PRE_CONFIG_COMPAT = {
286290'allocator': PYMEM_ALLOCATOR_NOT_SET,
287291'parse_argv': 0,
288292'configure_locale': 1,
@@ -291,15 +295,15 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase):
291295'utf8_mode': 0,
292296 }
293297if MS_WINDOWS:
294-DEFAULT_PRE_CONFIG.update({
298+PRE_CONFIG_COMPAT.update({
295299'legacy_windows_fs_encoding': 0,
296300 })
297-PYTHON_PRE_CONFIG = dict(DEFAULT_PRE_CONFIG,
301+PRE_CONFIG_PYTHON = dict(PRE_CONFIG_COMPAT,
298302parse_argv=1,
299303coerce_c_locale=GET_DEFAULT_CONFIG,
300304utf8_mode=GET_DEFAULT_CONFIG,
301305 )
302-ISOLATED_PRE_CONFIG = dict(DEFAULT_PRE_CONFIG,
306+PRE_CONFIG_ISOLATED = dict(PRE_CONFIG_COMPAT,
303307configure_locale=0,
304308isolated=1,
305309use_environment=0,
@@ -314,8 +318,8 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase):
314318'use_environment',
315319 ]
316320317-DEFAULT_CORE_CONFIG = {
318-'_config_init': CONFIG_INIT,
321+CORE_CONFIG_COMPAT = {
322+'_config_init': API_COMPAT,
319323'isolated': 0,
320324'use_environment': 1,
321325'dev_mode': 0,
@@ -379,15 +383,15 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase):
379383'_init_main': 1,
380384 }
381385if MS_WINDOWS:
382-DEFAULT_CORE_CONFIG.update({
386+CORE_CONFIG_COMPAT.update({
383387'legacy_windows_stdio': 0,
384388 })
385389386-PYTHON_CORE_CONFIG = dict(DEFAULT_CORE_CONFIG,
390+CORE_CONFIG_PYTHON = dict(CORE_CONFIG_COMPAT,
387391configure_c_stdio=1,
388392parse_argv=1,
389393 )
390-ISOLATED_CORE_CONFIG = dict(DEFAULT_CORE_CONFIG,
394+CORE_CONFIG_ISOLATED = dict(CORE_CONFIG_COMPAT,
391395isolated=1,
392396use_environment=0,
393397user_site_directory=0,
@@ -399,7 +403,7 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase):
399403pathconfig_warnings=0,
400404 )
401405if MS_WINDOWS:
402-ISOLATED_CORE_CONFIG['legacy_windows_stdio'] = 0
406+CORE_CONFIG_ISOLATED['legacy_windows_stdio'] = 0
403407404408# global config
405409DEFAULT_GLOBAL_CONFIG = {
@@ -492,7 +496,7 @@ def get_expected_config(self, expected_preconfig, expected, env, api,
492496if value is self.GET_DEFAULT_CONFIG:
493497expected_preconfig[key] = pre_config[key]
494498495-if not expected_preconfig['configure_locale'] or api == CONFIG_INIT:
499+if not expected_preconfig['configure_locale'] or api == API_COMPAT:
496500# there is no easy way to get the locale encoding before
497501# setlocale(LC_CTYPE, "") is called: don't test encodings
498502for key in ('filesystem_encoding', 'filesystem_errors',
@@ -579,32 +583,33 @@ def check_global_config(self, config):
579583580584self.assertEqual(config['global_config'], expected)
581585582-def check_config(self, testname, expected_config=None, expected_preconfig=None,
583-add_path=None, stderr=None, api=CONFIG_INIT):
586+def check_config(self, testname, expected_config=None,
587+expected_preconfig=None, add_path=None, stderr=None,
588+*, api):
584589env = dict(os.environ)
585590# Remove PYTHON* environment variables to get deterministic environment
586591for key in list(env):
587592if key.startswith('PYTHON'):
588593del env[key]
589594590-if api == CONFIG_INIT_ISOLATED:
591-default_preconfig = self.ISOLATED_PRE_CONFIG
592-elif api == CONFIG_INIT_PYTHON:
593-default_preconfig = self.PYTHON_PRE_CONFIG
595+if api == API_ISOLATED:
596+default_preconfig = self.PRE_CONFIG_ISOLATED
597+elif api == API_PYTHON:
598+default_preconfig = self.PRE_CONFIG_PYTHON
594599else:
595-default_preconfig = self.DEFAULT_PRE_CONFIG
600+default_preconfig = self.PRE_CONFIG_COMPAT
596601if expected_preconfig is None:
597602expected_preconfig = {}
598603expected_preconfig = dict(default_preconfig, **expected_preconfig)
599604if expected_config is None:
600605expected_config = {}
601606602-if api == CONFIG_INIT_PYTHON:
603-default_config = self.PYTHON_CORE_CONFIG
604-elif api == CONFIG_INIT_ISOLATED:
605-default_config = self.ISOLATED_CORE_CONFIG
607+if api == API_PYTHON:
608+default_config = self.CORE_CONFIG_PYTHON
609+elif api == API_ISOLATED:
610+default_config = self.CORE_CONFIG_ISOLATED
606611else:
607-default_config = self.DEFAULT_CORE_CONFIG
612+default_config = self.CORE_CONFIG_COMPAT
608613expected_config = dict(default_config, **expected_config)
609614expected_config['_config_init'] = api
610615@@ -627,7 +632,13 @@ def check_config(self, testname, expected_config=None, expected_preconfig=None,
627632self.check_global_config(config)
628633629634def test_init_default_config(self):
630-self.check_config("init_default_config", {}, {})
635+self.check_config("init_initialize_config", api=API_COMPAT)
636+637+def test_preinit_compat_config(self):
638+self.check_config("preinit_compat_config", api=API_COMPAT)
639+640+def test_init_compat_config(self):
641+self.check_config("init_compat_config", api=API_COMPAT)
631642632643def test_init_global_config(self):
633644preconfig = {
@@ -649,7 +660,8 @@ def test_init_global_config(self):
649660'user_site_directory': 0,
650661'pathconfig_warnings': 0,
651662 }
652-self.check_config("init_global_config", config, preconfig)
663+self.check_config("init_global_config", config, preconfig,
664+api=API_COMPAT)
653665654666def test_init_from_config(self):
655667preconfig = {
@@ -693,11 +705,13 @@ def test_init_from_config(self):
693705'check_hash_pycs_mode': 'always',
694706'pathconfig_warnings': 0,
695707 }
696-self.check_config("init_from_config", config, preconfig)
708+self.check_config("init_from_config", config, preconfig,
709+api=API_COMPAT)
697710698711def test_init_env(self):
699712preconfig = {
700713'allocator': PYMEM_ALLOCATOR_MALLOC,
714+'utf8_mode': 1,
701715 }
702716config = {
703717'use_hash_seed': 1,
@@ -718,21 +732,24 @@ def test_init_env(self):
718732'faulthandler': 1,
719733'warnoptions': ['EnvVar'],
720734 }
721-self.check_config("init_env", config, preconfig)
735+self.check_config("init_env", config, preconfig,
736+api=API_COMPAT)
722737723738def test_init_env_dev_mode(self):
724739preconfig = dict(allocator=PYMEM_ALLOCATOR_DEBUG)
725740config = dict(dev_mode=1,
726741faulthandler=1,
727742warnoptions=['default'])
728-self.check_config("init_env_dev_mode", config, preconfig)
743+self.check_config("init_env_dev_mode", config, preconfig,
744+api=API_COMPAT)
729745730746def test_init_env_dev_mode_alloc(self):
731747preconfig = dict(allocator=PYMEM_ALLOCATOR_MALLOC)
732748config = dict(dev_mode=1,
733749faulthandler=1,
734750warnoptions=['default'])
735-self.check_config("init_env_dev_mode_alloc", config, preconfig)
751+self.check_config("init_env_dev_mode_alloc", config, preconfig,
752+api=API_COMPAT)
736753737754def test_init_dev_mode(self):
738755preconfig = {
@@ -744,7 +761,7 @@ def test_init_dev_mode(self):
744761'warnoptions': ['default'],
745762 }
746763self.check_config("init_dev_mode", config, preconfig,
747-api=CONFIG_INIT_PYTHON)
764+api=API_PYTHON)
748765749766def test_preinit_parse_argv(self):
750767# Pre-initialize implicitly using argv: make sure that -X dev
@@ -761,7 +778,7 @@ def test_preinit_parse_argv(self):
761778'xoptions': ['dev'],
762779 }
763780self.check_config("preinit_parse_argv", config, preconfig,
764-api=CONFIG_INIT_PYTHON)
781+api=API_PYTHON)
765782766783def test_preinit_dont_parse_argv(self):
767784# -X dev must be ignored by isolated preconfiguration
@@ -774,15 +791,15 @@ def test_preinit_dont_parse_argv(self):
774791'isolated': 0,
775792 }
776793self.check_config("preinit_dont_parse_argv", config, preconfig,
777-api=CONFIG_INIT_ISOLATED)
794+api=API_ISOLATED)
778795779796def test_init_isolated_flag(self):
780797config = {
781798'isolated': 1,
782799'use_environment': 0,
783800'user_site_directory': 0,
784801 }
785-self.check_config("init_isolated_flag", config, api=CONFIG_INIT_PYTHON)
802+self.check_config("init_isolated_flag", config, api=API_PYTHON)
786803787804def test_preinit_isolated1(self):
788805# _PyPreConfig.isolated=1, _PyCoreConfig.isolated not set
@@ -791,7 +808,7 @@ def test_preinit_isolated1(self):
791808'use_environment': 0,
792809'user_site_directory': 0,
793810 }
794-self.check_config("preinit_isolated1", config)
811+self.check_config("preinit_isolated1", config, api=API_COMPAT)
795812796813def test_preinit_isolated2(self):
797814# _PyPreConfig.isolated=0, _PyCoreConfig.isolated=1
@@ -800,16 +817,16 @@ def test_preinit_isolated2(self):
800817'use_environment': 0,
801818'user_site_directory': 0,
802819 }
803-self.check_config("preinit_isolated2", config)
820+self.check_config("preinit_isolated2", config, api=API_COMPAT)
804821805822def test_preinit_isolated_config(self):
806-self.check_config("preinit_isolated_config", api=CONFIG_INIT_ISOLATED)
823+self.check_config("preinit_isolated_config", api=API_ISOLATED)
807824808825def test_init_isolated_config(self):
809-self.check_config("init_isolated_config", api=CONFIG_INIT_ISOLATED)
826+self.check_config("init_isolated_config", api=API_ISOLATED)
810827811828def test_init_python_config(self):
812-self.check_config("init_python_config", api=CONFIG_INIT_PYTHON)
829+self.check_config("init_python_config", api=API_PYTHON)
813830814831def test_init_dont_configure_locale(self):
815832# _PyPreConfig.configure_locale=0
@@ -818,15 +835,15 @@ def test_init_dont_configure_locale(self):
818835'coerce_c_locale': 0,
819836 }
820837self.check_config("init_dont_configure_locale", {}, preconfig,
821-api=CONFIG_INIT_PYTHON)
838+api=API_PYTHON)
822839823840def test_init_read_set(self):
824841core_config = {
825842'program_name': './init_read_set',
826843'executable': 'my_executable',
827844 }
828845self.check_config("init_read_set", core_config,
829-api=CONFIG_INIT_PYTHON,
846+api=API_PYTHON,
830847add_path="init_read_set_path")
831848832849def test_init_run_main(self):
@@ -838,8 +855,7 @@ def test_init_run_main(self):
838855'run_command': code + '\n',
839856'parse_argv': 1,
840857 }
841-self.check_config("init_run_main", core_config,
842-api=CONFIG_INIT_PYTHON)
858+self.check_config("init_run_main", core_config, api=API_PYTHON)
843859844860def test_init_main(self):
845861code = ('import _testinternalcapi, json; '
@@ -852,7 +868,7 @@ def test_init_main(self):
852868'_init_main': 0,
853869 }
854870self.check_config("init_main", core_config,
855-api=CONFIG_INIT_PYTHON,
871+api=API_PYTHON,
856872stderr="Run Python code before _Py_InitializeMain")
857873858874def test_init_parse_argv(self):
@@ -863,8 +879,7 @@ def test_init_parse_argv(self):
863879'run_command': 'pass\n',
864880'use_environment': 0,
865881 }
866-self.check_config("init_parse_argv", core_config,
867-api=CONFIG_INIT_PYTHON)
882+self.check_config("init_parse_argv", core_config, api=API_PYTHON)
868883869884def test_init_dont_parse_argv(self):
870885pre_config = {
@@ -876,7 +891,7 @@ def test_init_dont_parse_argv(self):
876891'program_name': './argv0',
877892 }
878893self.check_config("init_dont_parse_argv", core_config, pre_config,
879-api=CONFIG_INIT_PYTHON)
894+api=API_PYTHON)
880895881896882897if __name__ == "__main__":