(root)/
Python-3.11.7/
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  from test.support import MS_WINDOWS
      13  
      14  
      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              '_isolated_interpreter',
      88          ]
      89          if MS_WINDOWS:
      90              options.append('legacy_windows_stdio')
      91          for key in options:
      92              value_tests.append((key, invalid_uint))
      93              type_tests.append((key, "abc"))
      94              type_tests.append((key, 2.0))
      95  
      96          # wchar_t*
      97          for key in (
      98              'filesystem_encoding',
      99              'filesystem_errors',
     100              'stdio_encoding',
     101              'stdio_errors',
     102              'check_hash_pycs_mode',
     103              'program_name',
     104              'platlibdir',
     105              # optional wstr:
     106              # 'pythonpath_env'
     107              # 'home'
     108              # 'pycache_prefix'
     109              # 'run_command'
     110              # 'run_module'
     111              # 'run_filename'
     112              # 'executable'
     113              # 'prefix'
     114              # 'exec_prefix'
     115              # 'base_executable'
     116              # 'base_prefix'
     117              # 'base_exec_prefix'
     118          ):
     119              value_tests.append((key, invalid_wstr))
     120              type_tests.append((key, b'bytes'))
     121              type_tests.append((key, 123))
     122  
     123          # PyWideStringList
     124          for key in (
     125              'orig_argv',
     126              'argv',
     127              'xoptions',
     128              'warnoptions',
     129              'module_search_paths',
     130          ):
     131              value_tests.append((key, invalid_wstrlist))
     132              type_tests.append((key, 123))
     133              type_tests.append((key, "abc"))
     134              type_tests.append((key, [123]))
     135              type_tests.append((key, [b"bytes"]))
     136  
     137  
     138          if MS_WINDOWS:
     139              value_tests.append(('legacy_windows_stdio', invalid_uint))
     140  
     141          for exc_type, tests in (
     142              (ValueError, value_tests),
     143              (TypeError, type_tests),
     144          ):
     145              for key, value in tests:
     146                  config = self.old_config | {key: value}
     147                  with self.subTest(key=key, value=value, exc_type=exc_type):
     148                      with self.assertRaises(exc_type):
     149                          _testinternalcapi.set_config(config)
     150  
     151      def test_flags(self):
     152          for sys_attr, key, value in (
     153              ("debug", "parser_debug", 1),
     154              ("inspect", "inspect", 2),
     155              ("interactive", "interactive", 3),
     156              ("optimize", "optimization_level", 4),
     157              ("verbose", "verbose", 1),
     158              ("bytes_warning", "bytes_warning", 10),
     159              ("quiet", "quiet", 11),
     160              ("isolated", "isolated", 12),
     161          ):
     162              with self.subTest(sys=sys_attr, key=key, value=value):
     163                  self.set_config(**{key: value, 'parse_argv': 0})
     164                  self.assertEqual(getattr(sys.flags, sys_attr), value)
     165  
     166          self.set_config(write_bytecode=0)
     167          self.assertEqual(sys.flags.dont_write_bytecode, True)
     168          self.assertEqual(sys.dont_write_bytecode, True)
     169  
     170          self.set_config(write_bytecode=1)
     171          self.assertEqual(sys.flags.dont_write_bytecode, False)
     172          self.assertEqual(sys.dont_write_bytecode, False)
     173  
     174          self.set_config(user_site_directory=0, isolated=0)
     175          self.assertEqual(sys.flags.no_user_site, 1)
     176          self.set_config(user_site_directory=1, isolated=0)
     177          self.assertEqual(sys.flags.no_user_site, 0)
     178  
     179          self.set_config(site_import=0)
     180          self.assertEqual(sys.flags.no_site, 1)
     181          self.set_config(site_import=1)
     182          self.assertEqual(sys.flags.no_site, 0)
     183  
     184          self.set_config(dev_mode=0)
     185          self.assertEqual(sys.flags.dev_mode, False)
     186          self.set_config(dev_mode=1)
     187          self.assertEqual(sys.flags.dev_mode, True)
     188  
     189          self.set_config(use_environment=0, isolated=0)
     190          self.assertEqual(sys.flags.ignore_environment, 1)
     191          self.set_config(use_environment=1, isolated=0)
     192          self.assertEqual(sys.flags.ignore_environment, 0)
     193  
     194          self.set_config(use_hash_seed=1, hash_seed=0)
     195          self.assertEqual(sys.flags.hash_randomization, 0)
     196          self.set_config(use_hash_seed=0, hash_seed=0)
     197          self.assertEqual(sys.flags.hash_randomization, 1)
     198          self.set_config(use_hash_seed=1, hash_seed=123)
     199          self.assertEqual(sys.flags.hash_randomization, 1)
     200  
     201      def test_options(self):
     202          self.check(warnoptions=[])
     203          self.check(warnoptions=["default", "ignore"])
     204  
     205          self.set_config(xoptions=[])
     206          self.assertEqual(sys._xoptions, {})
     207          self.set_config(xoptions=["dev", "tracemalloc=5"])
     208          self.assertEqual(sys._xoptions, {"dev": True, "tracemalloc": "5"})
     209  
     210      def test_pathconfig(self):
     211          self.check(
     212              executable='executable',
     213              prefix="prefix",
     214              base_prefix="base_prefix",
     215              exec_prefix="exec_prefix",
     216              base_exec_prefix="base_exec_prefix",
     217              platlibdir="platlibdir")
     218  
     219          self.set_config(base_executable="base_executable")
     220          self.assertEqual(sys._base_executable, "base_executable")
     221  
     222          # When base_xxx is NULL, value is copied from xxxx
     223          self.set_config(
     224              executable='executable',
     225              prefix="prefix",
     226              exec_prefix="exec_prefix",
     227              base_executable=None,
     228              base_prefix=None,
     229              base_exec_prefix=None)
     230          self.assertEqual(sys._base_executable, "executable")
     231          self.assertEqual(sys.base_prefix, "prefix")
     232          self.assertEqual(sys.base_exec_prefix, "exec_prefix")
     233  
     234      def test_path(self):
     235          self.set_config(module_search_paths_set=1,
     236                          module_search_paths=['a', 'b', 'c'])
     237          self.assertEqual(sys.path, ['a', 'b', 'c'])
     238  
     239          # sys.path is reset if module_search_paths_set=0
     240          self.set_config(module_search_paths_set=0,
     241                          module_search_paths=['new_path'])
     242          self.assertNotEqual(sys.path, ['a', 'b', 'c'])
     243          self.assertNotEqual(sys.path, ['new_path'])
     244  
     245      def test_argv(self):
     246          self.set_config(parse_argv=0,
     247                          argv=['python_program', 'args'],
     248                          orig_argv=['orig', 'orig_args'])
     249          self.assertEqual(sys.argv, ['python_program', 'args'])
     250          self.assertEqual(sys.orig_argv, ['orig', 'orig_args'])
     251  
     252          self.set_config(parse_argv=0,
     253                          argv=[],
     254                          orig_argv=[])
     255          self.assertEqual(sys.argv, [''])
     256          self.assertEqual(sys.orig_argv, [])
     257  
     258      def test_pycache_prefix(self):
     259          self.check(pycache_prefix=None)
     260          self.check(pycache_prefix="pycache_prefix")
     261  
     262  
     263  if __name__ == "__main__":
     264      unittest.main()