17db96d56Sopenharmony_ci# bpo-42260: Test _PyInterpreterState_GetConfigCopy() 27db96d56Sopenharmony_ci# and _PyInterpreterState_SetConfig(). 37db96d56Sopenharmony_ci# 47db96d56Sopenharmony_ci# Test run in a subprocess since set_config(get_config()) 57db96d56Sopenharmony_ci# does reset sys attributes to their state of the Python startup 67db96d56Sopenharmony_ci# (before the site module is run). 77db96d56Sopenharmony_ci 87db96d56Sopenharmony_ciimport _testinternalcapi 97db96d56Sopenharmony_ciimport os 107db96d56Sopenharmony_ciimport sys 117db96d56Sopenharmony_ciimport unittest 127db96d56Sopenharmony_ci 137db96d56Sopenharmony_ci 147db96d56Sopenharmony_ciMS_WINDOWS = (os.name == 'nt') 157db96d56Sopenharmony_ciMAX_HASH_SEED = 4294967295 167db96d56Sopenharmony_ci 177db96d56Sopenharmony_ciclass SetConfigTests(unittest.TestCase): 187db96d56Sopenharmony_ci def setUp(self): 197db96d56Sopenharmony_ci self.old_config = _testinternalcapi.get_config() 207db96d56Sopenharmony_ci self.sys_copy = dict(sys.__dict__) 217db96d56Sopenharmony_ci 227db96d56Sopenharmony_ci def tearDown(self): 237db96d56Sopenharmony_ci _testinternalcapi.reset_path_config() 247db96d56Sopenharmony_ci _testinternalcapi.set_config(self.old_config) 257db96d56Sopenharmony_ci sys.__dict__.clear() 267db96d56Sopenharmony_ci sys.__dict__.update(self.sys_copy) 277db96d56Sopenharmony_ci 287db96d56Sopenharmony_ci def set_config(self, **kwargs): 297db96d56Sopenharmony_ci _testinternalcapi.set_config(self.old_config | kwargs) 307db96d56Sopenharmony_ci 317db96d56Sopenharmony_ci def check(self, **kwargs): 327db96d56Sopenharmony_ci self.set_config(**kwargs) 337db96d56Sopenharmony_ci for key, value in kwargs.items(): 347db96d56Sopenharmony_ci self.assertEqual(getattr(sys, key), value, 357db96d56Sopenharmony_ci (key, value)) 367db96d56Sopenharmony_ci 377db96d56Sopenharmony_ci def test_set_invalid(self): 387db96d56Sopenharmony_ci invalid_uint = -1 397db96d56Sopenharmony_ci NULL = None 407db96d56Sopenharmony_ci invalid_wstr = NULL 417db96d56Sopenharmony_ci # PyWideStringList strings must be non-NULL 427db96d56Sopenharmony_ci invalid_wstrlist = ["abc", NULL, "def"] 437db96d56Sopenharmony_ci 447db96d56Sopenharmony_ci type_tests = [] 457db96d56Sopenharmony_ci value_tests = [ 467db96d56Sopenharmony_ci # enum 477db96d56Sopenharmony_ci ('_config_init', 0), 487db96d56Sopenharmony_ci ('_config_init', 4), 497db96d56Sopenharmony_ci # unsigned long 507db96d56Sopenharmony_ci ("hash_seed", -1), 517db96d56Sopenharmony_ci ("hash_seed", MAX_HASH_SEED + 1), 527db96d56Sopenharmony_ci ] 537db96d56Sopenharmony_ci 547db96d56Sopenharmony_ci # int (unsigned) 557db96d56Sopenharmony_ci options = [ 567db96d56Sopenharmony_ci '_config_init', 577db96d56Sopenharmony_ci 'isolated', 587db96d56Sopenharmony_ci 'use_environment', 597db96d56Sopenharmony_ci 'dev_mode', 607db96d56Sopenharmony_ci 'install_signal_handlers', 617db96d56Sopenharmony_ci 'use_hash_seed', 627db96d56Sopenharmony_ci 'faulthandler', 637db96d56Sopenharmony_ci 'tracemalloc', 647db96d56Sopenharmony_ci 'import_time', 657db96d56Sopenharmony_ci 'code_debug_ranges', 667db96d56Sopenharmony_ci 'show_ref_count', 677db96d56Sopenharmony_ci 'dump_refs', 687db96d56Sopenharmony_ci 'malloc_stats', 697db96d56Sopenharmony_ci 'parse_argv', 707db96d56Sopenharmony_ci 'site_import', 717db96d56Sopenharmony_ci 'bytes_warning', 727db96d56Sopenharmony_ci 'inspect', 737db96d56Sopenharmony_ci 'interactive', 747db96d56Sopenharmony_ci 'optimization_level', 757db96d56Sopenharmony_ci 'parser_debug', 767db96d56Sopenharmony_ci 'write_bytecode', 777db96d56Sopenharmony_ci 'verbose', 787db96d56Sopenharmony_ci 'quiet', 797db96d56Sopenharmony_ci 'user_site_directory', 807db96d56Sopenharmony_ci 'configure_c_stdio', 817db96d56Sopenharmony_ci 'buffered_stdio', 827db96d56Sopenharmony_ci 'pathconfig_warnings', 837db96d56Sopenharmony_ci 'module_search_paths_set', 847db96d56Sopenharmony_ci 'skip_source_first_line', 857db96d56Sopenharmony_ci '_install_importlib', 867db96d56Sopenharmony_ci '_init_main', 877db96d56Sopenharmony_ci '_isolated_interpreter', 887db96d56Sopenharmony_ci ] 897db96d56Sopenharmony_ci if MS_WINDOWS: 907db96d56Sopenharmony_ci options.append('legacy_windows_stdio') 917db96d56Sopenharmony_ci for key in options: 927db96d56Sopenharmony_ci value_tests.append((key, invalid_uint)) 937db96d56Sopenharmony_ci type_tests.append((key, "abc")) 947db96d56Sopenharmony_ci type_tests.append((key, 2.0)) 957db96d56Sopenharmony_ci 967db96d56Sopenharmony_ci # wchar_t* 977db96d56Sopenharmony_ci for key in ( 987db96d56Sopenharmony_ci 'filesystem_encoding', 997db96d56Sopenharmony_ci 'filesystem_errors', 1007db96d56Sopenharmony_ci 'stdio_encoding', 1017db96d56Sopenharmony_ci 'stdio_errors', 1027db96d56Sopenharmony_ci 'check_hash_pycs_mode', 1037db96d56Sopenharmony_ci 'program_name', 1047db96d56Sopenharmony_ci 'platlibdir', 1057db96d56Sopenharmony_ci # optional wstr: 1067db96d56Sopenharmony_ci # 'pythonpath_env' 1077db96d56Sopenharmony_ci # 'home' 1087db96d56Sopenharmony_ci # 'pycache_prefix' 1097db96d56Sopenharmony_ci # 'run_command' 1107db96d56Sopenharmony_ci # 'run_module' 1117db96d56Sopenharmony_ci # 'run_filename' 1127db96d56Sopenharmony_ci # 'executable' 1137db96d56Sopenharmony_ci # 'prefix' 1147db96d56Sopenharmony_ci # 'exec_prefix' 1157db96d56Sopenharmony_ci # 'base_executable' 1167db96d56Sopenharmony_ci # 'base_prefix' 1177db96d56Sopenharmony_ci # 'base_exec_prefix' 1187db96d56Sopenharmony_ci ): 1197db96d56Sopenharmony_ci value_tests.append((key, invalid_wstr)) 1207db96d56Sopenharmony_ci type_tests.append((key, b'bytes')) 1217db96d56Sopenharmony_ci type_tests.append((key, 123)) 1227db96d56Sopenharmony_ci 1237db96d56Sopenharmony_ci # PyWideStringList 1247db96d56Sopenharmony_ci for key in ( 1257db96d56Sopenharmony_ci 'orig_argv', 1267db96d56Sopenharmony_ci 'argv', 1277db96d56Sopenharmony_ci 'xoptions', 1287db96d56Sopenharmony_ci 'warnoptions', 1297db96d56Sopenharmony_ci 'module_search_paths', 1307db96d56Sopenharmony_ci ): 1317db96d56Sopenharmony_ci value_tests.append((key, invalid_wstrlist)) 1327db96d56Sopenharmony_ci type_tests.append((key, 123)) 1337db96d56Sopenharmony_ci type_tests.append((key, "abc")) 1347db96d56Sopenharmony_ci type_tests.append((key, [123])) 1357db96d56Sopenharmony_ci type_tests.append((key, [b"bytes"])) 1367db96d56Sopenharmony_ci 1377db96d56Sopenharmony_ci 1387db96d56Sopenharmony_ci if MS_WINDOWS: 1397db96d56Sopenharmony_ci value_tests.append(('legacy_windows_stdio', invalid_uint)) 1407db96d56Sopenharmony_ci 1417db96d56Sopenharmony_ci for exc_type, tests in ( 1427db96d56Sopenharmony_ci (ValueError, value_tests), 1437db96d56Sopenharmony_ci (TypeError, type_tests), 1447db96d56Sopenharmony_ci ): 1457db96d56Sopenharmony_ci for key, value in tests: 1467db96d56Sopenharmony_ci config = self.old_config | {key: value} 1477db96d56Sopenharmony_ci with self.subTest(key=key, value=value, exc_type=exc_type): 1487db96d56Sopenharmony_ci with self.assertRaises(exc_type): 1497db96d56Sopenharmony_ci _testinternalcapi.set_config(config) 1507db96d56Sopenharmony_ci 1517db96d56Sopenharmony_ci def test_flags(self): 1527db96d56Sopenharmony_ci for sys_attr, key, value in ( 1537db96d56Sopenharmony_ci ("debug", "parser_debug", 1), 1547db96d56Sopenharmony_ci ("inspect", "inspect", 2), 1557db96d56Sopenharmony_ci ("interactive", "interactive", 3), 1567db96d56Sopenharmony_ci ("optimize", "optimization_level", 4), 1577db96d56Sopenharmony_ci ("verbose", "verbose", 1), 1587db96d56Sopenharmony_ci ("bytes_warning", "bytes_warning", 10), 1597db96d56Sopenharmony_ci ("quiet", "quiet", 11), 1607db96d56Sopenharmony_ci ("isolated", "isolated", 12), 1617db96d56Sopenharmony_ci ): 1627db96d56Sopenharmony_ci with self.subTest(sys=sys_attr, key=key, value=value): 1637db96d56Sopenharmony_ci self.set_config(**{key: value, 'parse_argv': 0}) 1647db96d56Sopenharmony_ci self.assertEqual(getattr(sys.flags, sys_attr), value) 1657db96d56Sopenharmony_ci 1667db96d56Sopenharmony_ci self.set_config(write_bytecode=0) 1677db96d56Sopenharmony_ci self.assertEqual(sys.flags.dont_write_bytecode, True) 1687db96d56Sopenharmony_ci self.assertEqual(sys.dont_write_bytecode, True) 1697db96d56Sopenharmony_ci 1707db96d56Sopenharmony_ci self.set_config(write_bytecode=1) 1717db96d56Sopenharmony_ci self.assertEqual(sys.flags.dont_write_bytecode, False) 1727db96d56Sopenharmony_ci self.assertEqual(sys.dont_write_bytecode, False) 1737db96d56Sopenharmony_ci 1747db96d56Sopenharmony_ci self.set_config(user_site_directory=0, isolated=0) 1757db96d56Sopenharmony_ci self.assertEqual(sys.flags.no_user_site, 1) 1767db96d56Sopenharmony_ci self.set_config(user_site_directory=1, isolated=0) 1777db96d56Sopenharmony_ci self.assertEqual(sys.flags.no_user_site, 0) 1787db96d56Sopenharmony_ci 1797db96d56Sopenharmony_ci self.set_config(site_import=0) 1807db96d56Sopenharmony_ci self.assertEqual(sys.flags.no_site, 1) 1817db96d56Sopenharmony_ci self.set_config(site_import=1) 1827db96d56Sopenharmony_ci self.assertEqual(sys.flags.no_site, 0) 1837db96d56Sopenharmony_ci 1847db96d56Sopenharmony_ci self.set_config(dev_mode=0) 1857db96d56Sopenharmony_ci self.assertEqual(sys.flags.dev_mode, False) 1867db96d56Sopenharmony_ci self.set_config(dev_mode=1) 1877db96d56Sopenharmony_ci self.assertEqual(sys.flags.dev_mode, True) 1887db96d56Sopenharmony_ci 1897db96d56Sopenharmony_ci self.set_config(use_environment=0, isolated=0) 1907db96d56Sopenharmony_ci self.assertEqual(sys.flags.ignore_environment, 1) 1917db96d56Sopenharmony_ci self.set_config(use_environment=1, isolated=0) 1927db96d56Sopenharmony_ci self.assertEqual(sys.flags.ignore_environment, 0) 1937db96d56Sopenharmony_ci 1947db96d56Sopenharmony_ci self.set_config(use_hash_seed=1, hash_seed=0) 1957db96d56Sopenharmony_ci self.assertEqual(sys.flags.hash_randomization, 0) 1967db96d56Sopenharmony_ci self.set_config(use_hash_seed=0, hash_seed=0) 1977db96d56Sopenharmony_ci self.assertEqual(sys.flags.hash_randomization, 1) 1987db96d56Sopenharmony_ci self.set_config(use_hash_seed=1, hash_seed=123) 1997db96d56Sopenharmony_ci self.assertEqual(sys.flags.hash_randomization, 1) 2007db96d56Sopenharmony_ci 2017db96d56Sopenharmony_ci def test_options(self): 2027db96d56Sopenharmony_ci self.check(warnoptions=[]) 2037db96d56Sopenharmony_ci self.check(warnoptions=["default", "ignore"]) 2047db96d56Sopenharmony_ci 2057db96d56Sopenharmony_ci self.set_config(xoptions=[]) 2067db96d56Sopenharmony_ci self.assertEqual(sys._xoptions, {}) 2077db96d56Sopenharmony_ci self.set_config(xoptions=["dev", "tracemalloc=5"]) 2087db96d56Sopenharmony_ci self.assertEqual(sys._xoptions, {"dev": True, "tracemalloc": "5"}) 2097db96d56Sopenharmony_ci 2107db96d56Sopenharmony_ci def test_pathconfig(self): 2117db96d56Sopenharmony_ci self.check( 2127db96d56Sopenharmony_ci executable='executable', 2137db96d56Sopenharmony_ci prefix="prefix", 2147db96d56Sopenharmony_ci base_prefix="base_prefix", 2157db96d56Sopenharmony_ci exec_prefix="exec_prefix", 2167db96d56Sopenharmony_ci base_exec_prefix="base_exec_prefix", 2177db96d56Sopenharmony_ci platlibdir="platlibdir") 2187db96d56Sopenharmony_ci 2197db96d56Sopenharmony_ci self.set_config(base_executable="base_executable") 2207db96d56Sopenharmony_ci self.assertEqual(sys._base_executable, "base_executable") 2217db96d56Sopenharmony_ci 2227db96d56Sopenharmony_ci # When base_xxx is NULL, value is copied from xxxx 2237db96d56Sopenharmony_ci self.set_config( 2247db96d56Sopenharmony_ci executable='executable', 2257db96d56Sopenharmony_ci prefix="prefix", 2267db96d56Sopenharmony_ci exec_prefix="exec_prefix", 2277db96d56Sopenharmony_ci base_executable=None, 2287db96d56Sopenharmony_ci base_prefix=None, 2297db96d56Sopenharmony_ci base_exec_prefix=None) 2307db96d56Sopenharmony_ci self.assertEqual(sys._base_executable, "executable") 2317db96d56Sopenharmony_ci self.assertEqual(sys.base_prefix, "prefix") 2327db96d56Sopenharmony_ci self.assertEqual(sys.base_exec_prefix, "exec_prefix") 2337db96d56Sopenharmony_ci 2347db96d56Sopenharmony_ci def test_path(self): 2357db96d56Sopenharmony_ci self.set_config(module_search_paths_set=1, 2367db96d56Sopenharmony_ci module_search_paths=['a', 'b', 'c']) 2377db96d56Sopenharmony_ci self.assertEqual(sys.path, ['a', 'b', 'c']) 2387db96d56Sopenharmony_ci 2397db96d56Sopenharmony_ci # sys.path is reset if module_search_paths_set=0 2407db96d56Sopenharmony_ci self.set_config(module_search_paths_set=0, 2417db96d56Sopenharmony_ci module_search_paths=['new_path']) 2427db96d56Sopenharmony_ci self.assertNotEqual(sys.path, ['a', 'b', 'c']) 2437db96d56Sopenharmony_ci self.assertNotEqual(sys.path, ['new_path']) 2447db96d56Sopenharmony_ci 2457db96d56Sopenharmony_ci def test_argv(self): 2467db96d56Sopenharmony_ci self.set_config(parse_argv=0, 2477db96d56Sopenharmony_ci argv=['python_program', 'args'], 2487db96d56Sopenharmony_ci orig_argv=['orig', 'orig_args']) 2497db96d56Sopenharmony_ci self.assertEqual(sys.argv, ['python_program', 'args']) 2507db96d56Sopenharmony_ci self.assertEqual(sys.orig_argv, ['orig', 'orig_args']) 2517db96d56Sopenharmony_ci 2527db96d56Sopenharmony_ci self.set_config(parse_argv=0, 2537db96d56Sopenharmony_ci argv=[], 2547db96d56Sopenharmony_ci orig_argv=[]) 2557db96d56Sopenharmony_ci self.assertEqual(sys.argv, ['']) 2567db96d56Sopenharmony_ci self.assertEqual(sys.orig_argv, []) 2577db96d56Sopenharmony_ci 2587db96d56Sopenharmony_ci def test_pycache_prefix(self): 2597db96d56Sopenharmony_ci self.check(pycache_prefix=None) 2607db96d56Sopenharmony_ci self.check(pycache_prefix="pycache_prefix") 2617db96d56Sopenharmony_ci 2627db96d56Sopenharmony_ci 2637db96d56Sopenharmony_ciif __name__ == "__main__": 2647db96d56Sopenharmony_ci unittest.main() 265