(root)/
Python-3.12.0/
Lib/
test/
_test_embed_set_config.py
       1  # bpo-42260: Test _PyInterpreterState_GetConfigCopy()
       2  # and _PyInterpreterState_SetConfig().
       3  #
       4  # Test run in a subprocess since set_config(get_config())
       5  # does reset sys attributes to their state of the Python startup
       6  # (before the site module is run).
       7  
       8  import _testinternalcapi
       9  import os
      10  import sys
      11  import unittest
      12  
      13  
      14  MS_WINDOWS = (os.name == 'nt')
      15  MAX_HASH_SEED = 4294967295
      16  
      17  class ESC[4;38;5;81mSetConfigTests(ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
      18      def setUp(self):
      19          self.old_config = _testinternalcapi.get_config()
      20          self.sys_copy = dict(sys.__dict__)
      21  
      22      def tearDown(self):
      23          _testinternalcapi.reset_path_config()
      24          _testinternalcapi.set_config(self.old_config)
      25          sys.__dict__.clear()
      26          sys.__dict__.update(self.sys_copy)
      27  
      28      def set_config(self, **kwargs):
      29          _testinternalcapi.set_config(self.old_config | kwargs)
      30  
      31      def check(self, **kwargs):
      32          self.set_config(**kwargs)
      33          for key, value in kwargs.items():
      34              self.assertEqual(getattr(sys, key), value,
      35                               (key, value))
      36  
      37      def test_set_invalid(self):
      38          invalid_uint = -1
      39          NULL = None
      40          invalid_wstr = NULL
      41          # PyWideStringList strings must be non-NULL
      42          invalid_wstrlist = ["abc", NULL, "def"]
      43  
      44          type_tests = []
      45          value_tests = [
      46              # enum
      47              ('_config_init', 0),
      48              ('_config_init', 4),
      49              # unsigned long
      50              ("hash_seed", -1),
      51              ("hash_seed", MAX_HASH_SEED + 1),
      52          ]
      53  
      54          # int (unsigned)
      55          options = [
      56              '_config_init',
      57              'isolated',
      58              'use_environment',
      59              'dev_mode',
      60              'install_signal_handlers',
      61              'use_hash_seed',
      62              'faulthandler',
      63              'tracemalloc',
      64              'import_time',
      65              'code_debug_ranges',
      66              'show_ref_count',
      67              'dump_refs',
      68              'malloc_stats',
      69              'parse_argv',
      70              'site_import',
      71              'bytes_warning',
      72              'inspect',
      73              'interactive',
      74              'optimization_level',
      75              'parser_debug',
      76              'write_bytecode',
      77              'verbose',
      78              'quiet',
      79              'user_site_directory',
      80              'configure_c_stdio',
      81              'buffered_stdio',
      82              'pathconfig_warnings',
      83              'module_search_paths_set',
      84              'skip_source_first_line',
      85              '_install_importlib',
      86              '_init_main',
      87          ]
      88          if MS_WINDOWS:
      89              options.append('legacy_windows_stdio')
      90          for key in options:
      91              value_tests.append((key, invalid_uint))
      92              type_tests.append((key, "abc"))
      93              type_tests.append((key, 2.0))
      94  
      95          # wchar_t*
      96          for key in (
      97              'filesystem_encoding',
      98              'filesystem_errors',
      99              'stdio_encoding',
     100              'stdio_errors',
     101              'check_hash_pycs_mode',
     102              'program_name',
     103              'platlibdir',
     104              # optional wstr:
     105              # 'pythonpath_env'
     106              # 'home'
     107              # 'pycache_prefix'
     108              # 'run_command'
     109              # 'run_module'
     110              # 'run_filename'
     111              # 'executable'
     112              # 'prefix'
     113              # 'exec_prefix'
     114              # 'base_executable'
     115              # 'base_prefix'
     116              # 'base_exec_prefix'
     117          ):
     118              value_tests.append((key, invalid_wstr))
     119              type_tests.append((key, b'bytes'))
     120              type_tests.append((key, 123))
     121  
     122          # PyWideStringList
     123          for key in (
     124              'orig_argv',
     125              'argv',
     126              'xoptions',
     127              'warnoptions',
     128              'module_search_paths',
     129          ):
     130              value_tests.append((key, invalid_wstrlist))
     131              type_tests.append((key, 123))
     132              type_tests.append((key, "abc"))
     133              type_tests.append((key, [123]))
     134              type_tests.append((key, [b"bytes"]))
     135  
     136  
     137          if MS_WINDOWS:
     138              value_tests.append(('legacy_windows_stdio', invalid_uint))
     139  
     140          for exc_type, tests in (
     141              (ValueError, value_tests),
     142              (TypeError, type_tests),
     143          ):
     144              for key, value in tests:
     145                  config = self.old_config | {key: value}
     146                  with self.subTest(key=key, value=value, exc_type=exc_type):
     147                      with self.assertRaises(exc_type):
     148                          _testinternalcapi.set_config(config)
     149  
     150      def test_flags(self):
     151          for sys_attr, key, value in (
     152              ("debug", "parser_debug", 1),
     153              ("inspect", "inspect", 2),
     154              ("interactive", "interactive", 3),
     155              ("optimize", "optimization_level", 4),
     156              ("verbose", "verbose", 1),
     157              ("bytes_warning", "bytes_warning", 10),
     158              ("quiet", "quiet", 11),
     159              ("isolated", "isolated", 12),
     160          ):
     161              with self.subTest(sys=sys_attr, key=key, value=value):
     162                  self.set_config(**{key: value, 'parse_argv': 0})
     163                  self.assertEqual(getattr(sys.flags, sys_attr), value)
     164  
     165          self.set_config(write_bytecode=0)
     166          self.assertEqual(sys.flags.dont_write_bytecode, True)
     167          self.assertEqual(sys.dont_write_bytecode, True)
     168  
     169          self.set_config(write_bytecode=1)
     170          self.assertEqual(sys.flags.dont_write_bytecode, False)
     171          self.assertEqual(sys.dont_write_bytecode, False)
     172  
     173          self.set_config(user_site_directory=0, isolated=0)
     174          self.assertEqual(sys.flags.no_user_site, 1)
     175          self.set_config(user_site_directory=1, isolated=0)
     176          self.assertEqual(sys.flags.no_user_site, 0)
     177  
     178          self.set_config(site_import=0)
     179          self.assertEqual(sys.flags.no_site, 1)
     180          self.set_config(site_import=1)
     181          self.assertEqual(sys.flags.no_site, 0)
     182  
     183          self.set_config(dev_mode=0)
     184          self.assertEqual(sys.flags.dev_mode, False)
     185          self.set_config(dev_mode=1)
     186          self.assertEqual(sys.flags.dev_mode, True)
     187  
     188          self.set_config(use_environment=0, isolated=0)
     189          self.assertEqual(sys.flags.ignore_environment, 1)
     190          self.set_config(use_environment=1, isolated=0)
     191          self.assertEqual(sys.flags.ignore_environment, 0)
     192  
     193          self.set_config(use_hash_seed=1, hash_seed=0)
     194          self.assertEqual(sys.flags.hash_randomization, 0)
     195          self.set_config(use_hash_seed=0, hash_seed=0)
     196          self.assertEqual(sys.flags.hash_randomization, 1)
     197          self.set_config(use_hash_seed=1, hash_seed=123)
     198          self.assertEqual(sys.flags.hash_randomization, 1)
     199  
     200      def test_options(self):
     201          self.check(warnoptions=[])
     202          self.check(warnoptions=["default", "ignore"])
     203  
     204          self.set_config(xoptions=[])
     205          self.assertEqual(sys._xoptions, {})
     206          self.set_config(xoptions=["dev", "tracemalloc=5"])
     207          self.assertEqual(sys._xoptions, {"dev": True, "tracemalloc": "5"})
     208  
     209      def test_pathconfig(self):
     210          self.check(
     211              executable='executable',
     212              prefix="prefix",
     213              base_prefix="base_prefix",
     214              exec_prefix="exec_prefix",
     215              base_exec_prefix="base_exec_prefix",
     216              platlibdir="platlibdir")
     217  
     218          self.set_config(base_executable="base_executable")
     219          self.assertEqual(sys._base_executable, "base_executable")
     220  
     221          # When base_xxx is NULL, value is copied from xxxx
     222          self.set_config(
     223              executable='executable',
     224              prefix="prefix",
     225              exec_prefix="exec_prefix",
     226              base_executable=None,
     227              base_prefix=None,
     228              base_exec_prefix=None)
     229          self.assertEqual(sys._base_executable, "executable")
     230          self.assertEqual(sys.base_prefix, "prefix")
     231          self.assertEqual(sys.base_exec_prefix, "exec_prefix")
     232  
     233      def test_path(self):
     234          self.set_config(module_search_paths_set=1,
     235                          module_search_paths=['a', 'b', 'c'])
     236          self.assertEqual(sys.path, ['a', 'b', 'c'])
     237  
     238          # sys.path is reset if module_search_paths_set=0
     239          self.set_config(module_search_paths_set=0,
     240                          module_search_paths=['new_path'])
     241          self.assertNotEqual(sys.path, ['a', 'b', 'c'])
     242          self.assertNotEqual(sys.path, ['new_path'])
     243  
     244      def test_argv(self):
     245          self.set_config(parse_argv=0,
     246                          argv=['python_program', 'args'],
     247                          orig_argv=['orig', 'orig_args'])
     248          self.assertEqual(sys.argv, ['python_program', 'args'])
     249          self.assertEqual(sys.orig_argv, ['orig', 'orig_args'])
     250  
     251          self.set_config(parse_argv=0,
     252                          argv=[],
     253                          orig_argv=[])
     254          self.assertEqual(sys.argv, [''])
     255          self.assertEqual(sys.orig_argv, [])
     256  
     257      def test_pycache_prefix(self):
     258          self.check(pycache_prefix=None)
     259          self.check(pycache_prefix="pycache_prefix")
     260  
     261  
     262  if __name__ == "__main__":
     263      unittest.main()