1717PYMEM_ALLOCATOR_DEBUG = 2
1818PYMEM_ALLOCATOR_MALLOC = 3
1919
20+ CONFIG_INIT = 0
21+ CONFIG_INIT_PYTHON = 1
22+ CONFIG_INIT_ISOLATED = 2
23+
2024
2125class EmbeddingTestsMixin :
2226 def setUp (self ):
@@ -280,20 +284,26 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase):
280284
281285 DEFAULT_PRE_CONFIG = {
282286 'allocator' : PYMEM_ALLOCATOR_NOT_SET ,
287+ 'parse_argv' : 0 ,
283288 'configure_locale' : 1 ,
284289 'coerce_c_locale' : 0 ,
285290 'coerce_c_locale_warn' : 0 ,
286291 'utf8_mode' : 0 ,
287292 }
293+ if MS_WINDOWS :
294+ DEFAULT_PRE_CONFIG .update ({
295+ 'legacy_windows_fs_encoding' : 0 ,
296+ })
297+ PYTHON_PRE_CONFIG = dict (DEFAULT_PRE_CONFIG ,
298+ parse_argv = 1 ,
299+ )
288300 ISOLATED_PRE_CONFIG = dict (DEFAULT_PRE_CONFIG ,
289301 configure_locale = 0 ,
290302 isolated = 1 ,
291303 use_environment = 0 ,
292304 utf8_mode = 0 ,
293305 dev_mode = 0 ,
294306 )
295- if MS_WINDOWS :
296- ISOLATED_PRE_CONFIG ['legacy_windows_fs_encoding' ] = 0
297307
298308 COPY_PRE_CONFIG = [
299309 'dev_mode' ,
@@ -302,6 +312,7 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase):
302312 ]
303313
304314 DEFAULT_CORE_CONFIG = {
315+ '_config_init' : CONFIG_INIT ,
305316 'isolated' : 0 ,
306317 'use_environment' : 1 ,
307318 'dev_mode' : 0 ,
@@ -365,9 +376,6 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase):
365376 '_init_main' : 1 ,
366377 }
367378 if MS_WINDOWS :
368- DEFAULT_PRE_CONFIG .update ({
369- 'legacy_windows_fs_encoding' : 0 ,
370- })
371379 DEFAULT_CORE_CONFIG .update ({
372380 'legacy_windows_stdio' : 0 ,
373381 })
@@ -439,13 +447,14 @@ def main_xoptions(self, xoptions_list):
439447
440448 def get_expected_config (self , expected_preconfig , expected , env , api ,
441449 add_path = None ):
442- if api == "python" :
450+ if api == CONFIG_INIT_PYTHON :
443451 default_config = self .PYTHON_CORE_CONFIG
444- elif api == "isolated" :
452+ elif api == CONFIG_INIT_ISOLATED :
445453 default_config = self .ISOLATED_CORE_CONFIG
446454 else :
447455 default_config = self .DEFAULT_CORE_CONFIG
448456 expected = dict (default_config , ** expected )
457+ expected ['_config_init' ] = api
449458
450459 code = textwrap .dedent ('''
451460 import json
@@ -519,9 +528,7 @@ def get_expected_config(self, expected_preconfig, expected, env, api,
519528 return expected
520529
521530 def check_pre_config (self , config , expected ):
522- pre_config = dict (config ['pre_config' ])
523- core_config = dict (config ['core_config' ])
524- self .assertEqual (pre_config , expected )
531+ self .assertEqual (config ['pre_config' ], expected )
525532
526533 def check_core_config (self , config , expected ):
527534 core_config = dict (config ['core_config' ])
@@ -554,7 +561,7 @@ def check_global_config(self, config):
554561 self .assertEqual (config ['global_config' ], expected )
555562
556563 def check_config (self , testname , expected_config = None , expected_preconfig = None ,
557- add_path = None , stderr = None , api = "default" ):
564+ add_path = None , stderr = None , api = CONFIG_INIT ):
558565 env = dict (os .environ )
559566 # Remove PYTHON* environment variables to get deterministic environment
560567 for key in list (env ):
@@ -565,8 +572,10 @@ def check_config(self, testname, expected_config=None, expected_preconfig=None,
565572 env ['PYTHONCOERCECLOCALE' ] = '0'
566573 env ['PYTHONUTF8' ] = '0'
567574
568- if api == "isolated" :
575+ if api == CONFIG_INIT_ISOLATED :
569576 default_preconfig = self .ISOLATED_PRE_CONFIG
577+ elif api == CONFIG_INIT_PYTHON :
578+ default_preconfig = self .PYTHON_PRE_CONFIG
570579 else :
571580 default_preconfig = self .DEFAULT_PRE_CONFIG
572581 if expected_preconfig is None :
@@ -719,15 +728,46 @@ def test_init_dev_mode(self):
719728 'dev_mode' : 1 ,
720729 'warnoptions' : ['default' ],
721730 }
722- self .check_config ("init_dev_mode" , config , preconfig , api = "python" )
731+ self .check_config ("init_dev_mode" , config , preconfig ,
732+ api = CONFIG_INIT_PYTHON )
733+
734+ def test_preinit_parse_argv (self ):
735+ # Pre-initialize implicitly using argv: make sure that -X dev
736+ # is used to configure the allocation in preinitialization
737+ preconfig = {
738+ 'allocator' : PYMEM_ALLOCATOR_DEBUG ,
739+ }
740+ config = {
741+ 'argv' : ['script.py' ],
742+ 'run_filename' : 'script.py' ,
743+ 'dev_mode' : 1 ,
744+ 'faulthandler' : 1 ,
745+ 'warnoptions' : ['default' ],
746+ 'xoptions' : ['dev' ],
747+ }
748+ self .check_config ("preinit_parse_argv" , config , preconfig ,
749+ api = CONFIG_INIT_PYTHON )
750+
751+ def test_preinit_dont_parse_argv (self ):
752+ # -X dev must be ignored by isolated preconfiguration
753+ preconfig = {
754+ 'isolated' : 0 ,
755+ }
756+ config = {
757+ 'argv' : ["python3" , "-E" , "-I" ,
758+ "-X" , "dev" , "-X" , "utf8" , "script.py" ],
759+ 'isolated' : 0 ,
760+ }
761+ self .check_config ("preinit_dont_parse_argv" , config , preconfig ,
762+ api = CONFIG_INIT_ISOLATED )
723763
724764 def test_init_isolated_flag (self ):
725765 config = {
726766 'isolated' : 1 ,
727767 'use_environment' : 0 ,
728768 'user_site_directory' : 0 ,
729769 }
730- self .check_config ("init_isolated_flag" , config , api = "python" )
770+ self .check_config ("init_isolated_flag" , config , api = CONFIG_INIT_PYTHON )
731771
732772 def test_preinit_isolated1 (self ):
733773 # _PyPreConfig.isolated=1, _PyCoreConfig.isolated not set
@@ -747,25 +787,30 @@ def test_preinit_isolated2(self):
747787 }
748788 self .check_config ("preinit_isolated2" , config )
749789
790+ def test_preinit_isolated_config (self ):
791+ self .check_config ("preinit_isolated_config" , api = CONFIG_INIT_ISOLATED )
792+
750793 def test_init_isolated_config (self ):
751- self .check_config ("init_isolated_config" , api = "isolated" )
794+ self .check_config ("init_isolated_config" , api = CONFIG_INIT_ISOLATED )
752795
753796 def test_init_python_config (self ):
754- self .check_config ("init_python_config" , api = "python" )
797+ self .check_config ("init_python_config" , api = CONFIG_INIT_PYTHON )
755798
756799 def test_init_dont_configure_locale (self ):
757800 # _PyPreConfig.configure_locale=0
758801 preconfig = {
759802 'configure_locale' : 0 ,
760803 }
761- self .check_config ("init_dont_configure_locale" , {}, preconfig , api = "python" )
804+ self .check_config ("init_dont_configure_locale" , {}, preconfig ,
805+ api = CONFIG_INIT_PYTHON )
762806
763807 def test_init_read_set (self ):
764808 core_config = {
765809 'program_name' : './init_read_set' ,
766810 'executable' : 'my_executable' ,
767811 }
768- self .check_config ("init_read_set" , core_config , api = "python" ,
812+ self .check_config ("init_read_set" , core_config ,
813+ api = CONFIG_INIT_PYTHON ,
769814 add_path = "init_read_set_path" )
770815
771816 def test_init_run_main (self ):
@@ -777,7 +822,8 @@ def test_init_run_main(self):
777822 'run_command' : code + '\n ' ,
778823 'parse_argv' : 1 ,
779824 }
780- self .check_config ("init_run_main" , core_config , api = "python" )
825+ self .check_config ("init_run_main" , core_config ,
826+ api = CONFIG_INIT_PYTHON )
781827
782828 def test_init_main (self ):
783829 code = ('import _testinternalcapi, json; '
@@ -789,7 +835,8 @@ def test_init_main(self):
789835 'parse_argv' : 1 ,
790836 '_init_main' : 0 ,
791837 }
792- self .check_config ("init_main" , core_config , api = "python" ,
838+ self .check_config ("init_main" , core_config ,
839+ api = CONFIG_INIT_PYTHON ,
793840 stderr = "Run Python code before _Py_InitializeMain" )
794841
795842 def test_init_parse_argv (self ):
@@ -800,15 +847,20 @@ def test_init_parse_argv(self):
800847 'run_command' : 'pass\n ' ,
801848 'use_environment' : 0 ,
802849 }
803- self .check_config ("init_parse_argv" , core_config , api = "python" )
850+ self .check_config ("init_parse_argv" , core_config ,
851+ api = CONFIG_INIT_PYTHON )
804852
805853 def test_init_dont_parse_argv (self ):
854+ pre_config = {
855+ 'parse_argv' : 0 ,
856+ }
806857 core_config = {
807858 'parse_argv' : 0 ,
808859 'argv' : ['./argv0' , '-E' , '-c' , 'pass' , 'arg1' , '-v' , 'arg3' ],
809860 'program_name' : './argv0' ,
810861 }
811- self .check_config ("init_dont_parse_argv" , core_config , api = "python" )
862+ self .check_config ("init_dont_parse_argv" , core_config , pre_config ,
863+ api = CONFIG_INIT_PYTHON )
812864
813865
814866if __name__ == "__main__" :
0 commit comments