blob: a39ef2babbdb0e36726b46142ee025a6394fd09d [file] [log] [blame]
Nick Coghlan39f0bb52017-11-28 08:11:51 +10001# Run the tests in Programs/_testembed.c (tests for the CPython embedding APIs)
2from test import support
3import unittest
4
5from collections import namedtuple
Victor Stinner7ddd56f2018-11-14 00:24:28 +01006import json
Nick Coghlan39f0bb52017-11-28 08:11:51 +10007import os
Michael Feltd2067312018-09-15 11:28:31 +02008import platform
Nick Coghlan39f0bb52017-11-28 08:11:51 +10009import re
10import subprocess
11import sys
Victor Stinnera6537fb2018-11-26 11:54:12 +010012import textwrap
Nick Coghlan39f0bb52017-11-28 08:11:51 +100013
14
Victor Stinner01de89c2018-11-14 17:39:45 +010015MS_WINDOWS = (os.name == 'nt')
Victor Stinner022be022019-05-22 23:58:50 +020016
Victor Stinnerb16b4e42019-05-17 15:20:52 +020017PYMEM_ALLOCATOR_NOT_SET = 0
18PYMEM_ALLOCATOR_DEBUG = 2
19PYMEM_ALLOCATOR_MALLOC = 3
Victor Stinner01de89c2018-11-14 17:39:45 +010020
Victor Stinner022be022019-05-22 23:58:50 +020021# _PyCoreConfig_InitCompatConfig()
22API_COMPAT = 1
23# _PyCoreConfig_InitPythonConfig()
24API_PYTHON = 2
25# _PyCoreConfig_InitIsolatedConfig()
26API_ISOLATED = 3
Victor Stinner6d1c4672019-05-20 11:02:00 +020027
Victor Stinner01de89c2018-11-14 17:39:45 +010028
Victor Stinner56b29b62018-07-26 18:57:56 +020029class EmbeddingTestsMixin:
Nick Coghlan39f0bb52017-11-28 08:11:51 +100030 def setUp(self):
31 here = os.path.abspath(__file__)
32 basepath = os.path.dirname(os.path.dirname(os.path.dirname(here)))
33 exename = "_testembed"
Victor Stinner01de89c2018-11-14 17:39:45 +010034 if MS_WINDOWS:
Nick Coghlan39f0bb52017-11-28 08:11:51 +100035 ext = ("_d" if "_d" in sys.executable else "") + ".exe"
36 exename += ext
37 exepath = os.path.dirname(sys.executable)
38 else:
39 exepath = os.path.join(basepath, "Programs")
40 self.test_exe = exe = os.path.join(exepath, exename)
41 if not os.path.exists(exe):
42 self.skipTest("%r doesn't exist" % exe)
43 # This is needed otherwise we get a fatal error:
44 # "Py_Initialize: Unable to get the locale encoding
45 # LookupError: no codec search functions registered: can't find encoding"
46 self.oldcwd = os.getcwd()
47 os.chdir(basepath)
48
49 def tearDown(self):
50 os.chdir(self.oldcwd)
51
52 def run_embedded_interpreter(self, *args, env=None):
53 """Runs a test in the embedded interpreter"""
54 cmd = [self.test_exe]
55 cmd.extend(args)
Victor Stinner01de89c2018-11-14 17:39:45 +010056 if env is not None and MS_WINDOWS:
Nick Coghlan39f0bb52017-11-28 08:11:51 +100057 # Windows requires at least the SYSTEMROOT environment variable to
58 # start Python.
59 env = env.copy()
60 env['SYSTEMROOT'] = os.environ['SYSTEMROOT']
61
62 p = subprocess.Popen(cmd,
63 stdout=subprocess.PIPE,
64 stderr=subprocess.PIPE,
65 universal_newlines=True,
66 env=env)
Victor Stinner2f549082019-03-29 15:13:46 +010067 try:
68 (out, err) = p.communicate()
69 except:
70 p.terminate()
71 p.wait()
72 raise
Nick Coghlan39f0bb52017-11-28 08:11:51 +100073 if p.returncode != 0 and support.verbose:
74 print(f"--- {cmd} failed ---")
75 print(f"stdout:\n{out}")
Nick Coghlanbc77eff2018-03-25 20:44:30 +100076 print(f"stderr:\n{err}")
Nick Coghlan39f0bb52017-11-28 08:11:51 +100077 print(f"------")
78
79 self.assertEqual(p.returncode, 0,
80 "bad returncode %d, stderr is %r" %
81 (p.returncode, err))
82 return out, err
83
84 def run_repeated_init_and_subinterpreters(self):
Victor Stinner5edcf262019-05-23 00:57:57 +020085 out, err = self.run_embedded_interpreter("test_repeated_init_and_subinterpreters")
Nick Coghlan39f0bb52017-11-28 08:11:51 +100086 self.assertEqual(err, "")
87
88 # The output from _testembed looks like this:
89 # --- Pass 0 ---
90 # interp 0 <0x1cf9330>, thread state <0x1cf9700>: id(modules) = 139650431942728
91 # interp 1 <0x1d4f690>, thread state <0x1d35350>: id(modules) = 139650431165784
92 # interp 2 <0x1d5a690>, thread state <0x1d99ed0>: id(modules) = 139650413140368
93 # interp 3 <0x1d4f690>, thread state <0x1dc3340>: id(modules) = 139650412862200
94 # interp 0 <0x1cf9330>, thread state <0x1cf9700>: id(modules) = 139650431942728
95 # --- Pass 1 ---
96 # ...
97
98 interp_pat = (r"^interp (\d+) <(0x[\dA-F]+)>, "
99 r"thread state <(0x[\dA-F]+)>: "
100 r"id\(modules\) = ([\d]+)$")
101 Interp = namedtuple("Interp", "id interp tstate modules")
102
103 numloops = 0
104 current_run = []
105 for line in out.splitlines():
106 if line == "--- Pass {} ---".format(numloops):
107 self.assertEqual(len(current_run), 0)
Nick Coghlanbc77eff2018-03-25 20:44:30 +1000108 if support.verbose > 1:
Nick Coghlan39f0bb52017-11-28 08:11:51 +1000109 print(line)
110 numloops += 1
111 continue
112
113 self.assertLess(len(current_run), 5)
114 match = re.match(interp_pat, line)
115 if match is None:
116 self.assertRegex(line, interp_pat)
117
118 # Parse the line from the loop. The first line is the main
119 # interpreter and the 3 afterward are subinterpreters.
120 interp = Interp(*match.groups())
Nick Coghlanbc77eff2018-03-25 20:44:30 +1000121 if support.verbose > 1:
Nick Coghlan39f0bb52017-11-28 08:11:51 +1000122 print(interp)
123 self.assertTrue(interp.interp)
124 self.assertTrue(interp.tstate)
125 self.assertTrue(interp.modules)
126 current_run.append(interp)
127
128 # The last line in the loop should be the same as the first.
129 if len(current_run) == 5:
130 main = current_run[0]
131 self.assertEqual(interp, main)
132 yield current_run
133 current_run = []
134
Victor Stinner56b29b62018-07-26 18:57:56 +0200135
136class EmbeddingTests(EmbeddingTestsMixin, unittest.TestCase):
Nick Coghlan39f0bb52017-11-28 08:11:51 +1000137 def test_subinterps_main(self):
138 for run in self.run_repeated_init_and_subinterpreters():
139 main = run[0]
140
141 self.assertEqual(main.id, '0')
142
143 def test_subinterps_different_ids(self):
144 for run in self.run_repeated_init_and_subinterpreters():
145 main, *subs, _ = run
146
147 mainid = int(main.id)
148 for i, sub in enumerate(subs):
149 self.assertEqual(sub.id, str(mainid + i + 1))
150
151 def test_subinterps_distinct_state(self):
152 for run in self.run_repeated_init_and_subinterpreters():
153 main, *subs, _ = run
154
155 if '0x0' in main:
156 # XXX Fix on Windows (and other platforms): something
157 # is going on with the pointers in Programs/_testembed.c.
158 # interp.interp is 0x0 and interp.modules is the same
159 # between interpreters.
160 raise unittest.SkipTest('platform prints pointers as 0x0')
161
162 for sub in subs:
163 # A new subinterpreter may have the same
164 # PyInterpreterState pointer as a previous one if
165 # the earlier one has already been destroyed. So
166 # we compare with the main interpreter. The same
167 # applies to tstate.
168 self.assertNotEqual(sub.interp, main.interp)
169 self.assertNotEqual(sub.tstate, main.tstate)
170 self.assertNotEqual(sub.modules, main.modules)
171
172 def test_forced_io_encoding(self):
173 # Checks forced configuration of embedded interpreter IO streams
174 env = dict(os.environ, PYTHONIOENCODING="utf-8:surrogateescape")
Victor Stinner5edcf262019-05-23 00:57:57 +0200175 out, err = self.run_embedded_interpreter("test_forced_io_encoding", env=env)
Nick Coghlan39f0bb52017-11-28 08:11:51 +1000176 if support.verbose > 1:
177 print()
178 print(out)
179 print(err)
180 expected_stream_encoding = "utf-8"
181 expected_errors = "surrogateescape"
182 expected_output = '\n'.join([
183 "--- Use defaults ---",
184 "Expected encoding: default",
185 "Expected errors: default",
186 "stdin: {in_encoding}:{errors}",
187 "stdout: {out_encoding}:{errors}",
188 "stderr: {out_encoding}:backslashreplace",
189 "--- Set errors only ---",
190 "Expected encoding: default",
191 "Expected errors: ignore",
192 "stdin: {in_encoding}:ignore",
193 "stdout: {out_encoding}:ignore",
194 "stderr: {out_encoding}:backslashreplace",
195 "--- Set encoding only ---",
Victor Stinner9e4994d2018-08-28 23:26:33 +0200196 "Expected encoding: iso8859-1",
Nick Coghlan39f0bb52017-11-28 08:11:51 +1000197 "Expected errors: default",
Victor Stinner9e4994d2018-08-28 23:26:33 +0200198 "stdin: iso8859-1:{errors}",
199 "stdout: iso8859-1:{errors}",
200 "stderr: iso8859-1:backslashreplace",
Nick Coghlan39f0bb52017-11-28 08:11:51 +1000201 "--- Set encoding and errors ---",
Victor Stinner9e4994d2018-08-28 23:26:33 +0200202 "Expected encoding: iso8859-1",
Nick Coghlan39f0bb52017-11-28 08:11:51 +1000203 "Expected errors: replace",
Victor Stinner9e4994d2018-08-28 23:26:33 +0200204 "stdin: iso8859-1:replace",
205 "stdout: iso8859-1:replace",
206 "stderr: iso8859-1:backslashreplace"])
Nick Coghlan39f0bb52017-11-28 08:11:51 +1000207 expected_output = expected_output.format(
208 in_encoding=expected_stream_encoding,
209 out_encoding=expected_stream_encoding,
210 errors=expected_errors)
211 # This is useful if we ever trip over odd platform behaviour
212 self.maxDiff = None
213 self.assertEqual(out.strip(), expected_output)
214
215 def test_pre_initialization_api(self):
216 """
Nick Coghlanbc77eff2018-03-25 20:44:30 +1000217 Checks some key parts of the C-API that need to work before the runtine
Nick Coghlan39f0bb52017-11-28 08:11:51 +1000218 is initialized (via Py_Initialize()).
219 """
220 env = dict(os.environ, PYTHONPATH=os.pathsep.join(sys.path))
Victor Stinner5edcf262019-05-23 00:57:57 +0200221 out, err = self.run_embedded_interpreter("test_pre_initialization_api", env=env)
Victor Stinner01de89c2018-11-14 17:39:45 +0100222 if MS_WINDOWS:
Nick Coghlanbc77eff2018-03-25 20:44:30 +1000223 expected_path = self.test_exe
224 else:
225 expected_path = os.path.join(os.getcwd(), "spam")
226 expected_output = f"sys.executable: {expected_path}\n"
227 self.assertIn(expected_output, out)
228 self.assertEqual(err, '')
229
230 def test_pre_initialization_sys_options(self):
231 """
232 Checks that sys.warnoptions and sys._xoptions can be set before the
233 runtime is initialized (otherwise they won't be effective).
234 """
Pablo Galindo41148462018-04-27 13:23:13 +0100235 env = dict(os.environ, PYTHONPATH=os.pathsep.join(sys.path))
Nick Coghlanbc77eff2018-03-25 20:44:30 +1000236 out, err = self.run_embedded_interpreter(
Victor Stinner5edcf262019-05-23 00:57:57 +0200237 "test_pre_initialization_sys_options", env=env)
Nick Coghlanbc77eff2018-03-25 20:44:30 +1000238 expected_output = (
239 "sys.warnoptions: ['once', 'module', 'default']\n"
240 "sys._xoptions: {'not_an_option': '1', 'also_not_an_option': '2'}\n"
241 "warnings.filters[:3]: ['default', 'module', 'once']\n"
242 )
243 self.assertIn(expected_output, out)
Nick Coghlan39f0bb52017-11-28 08:11:51 +1000244 self.assertEqual(err, '')
245
Victor Stinnerb4d1e1f2017-11-30 22:05:00 +0100246 def test_bpo20891(self):
247 """
248 bpo-20891: Calling PyGILState_Ensure in a non-Python thread before
249 calling PyEval_InitThreads() must not crash. PyGILState_Ensure() must
250 call PyEval_InitThreads() for us in this case.
251 """
Victor Stinner5edcf262019-05-23 00:57:57 +0200252 out, err = self.run_embedded_interpreter("test_bpo20891")
Victor Stinnerb4d1e1f2017-11-30 22:05:00 +0100253 self.assertEqual(out, '')
254 self.assertEqual(err, '')
255
Victor Stinner209abf72018-06-22 19:14:51 +0200256 def test_initialize_twice(self):
257 """
258 bpo-33932: Calling Py_Initialize() twice should do nothing (and not
259 crash!).
260 """
Victor Stinner5edcf262019-05-23 00:57:57 +0200261 out, err = self.run_embedded_interpreter("test_initialize_twice")
Victor Stinner209abf72018-06-22 19:14:51 +0200262 self.assertEqual(out, '')
263 self.assertEqual(err, '')
264
Victor Stinnerfb47bca2018-07-20 17:34:23 +0200265 def test_initialize_pymain(self):
266 """
267 bpo-34008: Calling Py_Main() after Py_Initialize() must not fail.
268 """
Victor Stinner5edcf262019-05-23 00:57:57 +0200269 out, err = self.run_embedded_interpreter("test_initialize_pymain")
Victor Stinnerfb47bca2018-07-20 17:34:23 +0200270 self.assertEqual(out.rstrip(), "Py_Main() after Py_Initialize: sys.argv=['-c', 'arg2']")
271 self.assertEqual(err, '')
272
Victor Stinner2f549082019-03-29 15:13:46 +0100273 def test_run_main(self):
Victor Stinner5edcf262019-05-23 00:57:57 +0200274 out, err = self.run_embedded_interpreter("test_run_main")
Victor Stinner331a6a52019-05-27 16:39:22 +0200275 self.assertEqual(out.rstrip(), "Py_RunMain(): sys.argv=['-c', 'arg2']")
Victor Stinner2f549082019-03-29 15:13:46 +0100276 self.assertEqual(err, '')
277
Nick Coghlan39f0bb52017-11-28 08:11:51 +1000278
Victor Stinner56b29b62018-07-26 18:57:56 +0200279class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase):
280 maxDiff = 4096
Victor Stinner01de89c2018-11-14 17:39:45 +0100281 UTF8_MODE_ERRORS = ('surrogatepass' if MS_WINDOWS else 'surrogateescape')
282
Victor Stinnerbcfbbd72019-05-17 22:44:16 +0200283 # Marker to read the default configuration: get_default_config()
Victor Stinnera6537fb2018-11-26 11:54:12 +0100284 GET_DEFAULT_CONFIG = object()
Victor Stinnerbcfbbd72019-05-17 22:44:16 +0200285
286 # Marker to ignore a configuration parameter
287 IGNORE_CONFIG = object()
288
Victor Stinner022be022019-05-22 23:58:50 +0200289 PRE_CONFIG_COMPAT = {
Victor Stinner20e1e252019-05-23 04:12:27 +0200290 '_config_init': API_COMPAT,
Victor Stinnerb16b4e42019-05-17 15:20:52 +0200291 'allocator': PYMEM_ALLOCATOR_NOT_SET,
Victor Stinner6d1c4672019-05-20 11:02:00 +0200292 'parse_argv': 0,
Victor Stinnerbcfbbd72019-05-17 22:44:16 +0200293 'configure_locale': 1,
Victor Stinner1075d162019-03-25 23:19:57 +0100294 'coerce_c_locale': 0,
295 'coerce_c_locale_warn': 0,
Victor Stinner1075d162019-03-25 23:19:57 +0100296 'utf8_mode': 0,
297 }
Victor Stinner6d1c4672019-05-20 11:02:00 +0200298 if MS_WINDOWS:
Victor Stinner022be022019-05-22 23:58:50 +0200299 PRE_CONFIG_COMPAT.update({
Victor Stinner6d1c4672019-05-20 11:02:00 +0200300 'legacy_windows_fs_encoding': 0,
301 })
Victor Stinner022be022019-05-22 23:58:50 +0200302 PRE_CONFIG_PYTHON = dict(PRE_CONFIG_COMPAT,
Victor Stinner20e1e252019-05-23 04:12:27 +0200303 _config_init=API_PYTHON,
Victor Stinner6d1c4672019-05-20 11:02:00 +0200304 parse_argv=1,
Victor Stinner425717f2019-05-20 16:38:48 +0200305 coerce_c_locale=GET_DEFAULT_CONFIG,
306 utf8_mode=GET_DEFAULT_CONFIG,
Victor Stinner6d1c4672019-05-20 11:02:00 +0200307 )
Victor Stinner022be022019-05-22 23:58:50 +0200308 PRE_CONFIG_ISOLATED = dict(PRE_CONFIG_COMPAT,
Victor Stinner20e1e252019-05-23 04:12:27 +0200309 _config_init=API_ISOLATED,
Victor Stinnerbab0db62019-05-18 03:21:27 +0200310 configure_locale=0,
311 isolated=1,
312 use_environment=0,
313 utf8_mode=0,
314 dev_mode=0,
Victor Stinner425717f2019-05-20 16:38:48 +0200315 coerce_c_locale=0,
Victor Stinnerbab0db62019-05-18 03:21:27 +0200316 )
Victor Stinnerbab0db62019-05-18 03:21:27 +0200317
Victor Stinner20004952019-03-26 02:31:11 +0100318 COPY_PRE_CONFIG = [
319 'dev_mode',
320 'isolated',
321 'use_environment',
322 ]
323
Victor Stinner331a6a52019-05-27 16:39:22 +0200324 CONFIG_COMPAT = {
Victor Stinner022be022019-05-22 23:58:50 +0200325 '_config_init': API_COMPAT,
Victor Stinner20004952019-03-26 02:31:11 +0100326 'isolated': 0,
327 'use_environment': 1,
328 'dev_mode': 0,
329
Victor Stinner56b29b62018-07-26 18:57:56 +0200330 'install_signal_handlers': 1,
Victor Stinner56b29b62018-07-26 18:57:56 +0200331 'use_hash_seed': 0,
332 'hash_seed': 0,
Victor Stinner56b29b62018-07-26 18:57:56 +0200333 'faulthandler': 0,
334 'tracemalloc': 0,
335 'import_time': 0,
336 'show_ref_count': 0,
337 'show_alloc_count': 0,
338 'dump_refs': 0,
339 'malloc_stats': 0,
Victor Stinner56b29b62018-07-26 18:57:56 +0200340
Victor Stinnera6537fb2018-11-26 11:54:12 +0100341 'filesystem_encoding': GET_DEFAULT_CONFIG,
342 'filesystem_errors': GET_DEFAULT_CONFIG,
Victor Stinnerc5989cd2018-08-29 19:32:47 +0200343
Victor Stinner7ddd56f2018-11-14 00:24:28 +0100344 'pycache_prefix': None,
Victor Stinner91c99872019-05-14 22:01:51 +0200345 'program_name': GET_DEFAULT_CONFIG,
Victor Stinnercab5d072019-05-17 19:01:14 +0200346 'parse_argv': 0,
Victor Stinner62599762019-03-15 16:03:23 +0100347 'argv': [""],
Victor Stinner7ddd56f2018-11-14 00:24:28 +0100348
349 'xoptions': [],
350 'warnoptions': [],
Victor Stinner56b29b62018-07-26 18:57:56 +0200351
Victor Stinner331a6a52019-05-27 16:39:22 +0200352 'pythonpath_env': None,
Victor Stinner01de89c2018-11-14 17:39:45 +0100353 'home': None,
Victor Stinner91c99872019-05-14 22:01:51 +0200354 'executable': GET_DEFAULT_CONFIG,
Victor Stinnera6537fb2018-11-26 11:54:12 +0100355
356 'prefix': GET_DEFAULT_CONFIG,
357 'base_prefix': GET_DEFAULT_CONFIG,
358 'exec_prefix': GET_DEFAULT_CONFIG,
359 'base_exec_prefix': GET_DEFAULT_CONFIG,
Victor Stinner5eb8b072019-05-15 02:12:48 +0200360 'module_search_paths': GET_DEFAULT_CONFIG,
Victor Stinner01de89c2018-11-14 17:39:45 +0100361
Victor Stinner56b29b62018-07-26 18:57:56 +0200362 'site_import': 1,
363 'bytes_warning': 0,
364 'inspect': 0,
365 'interactive': 0,
366 'optimization_level': 0,
Victor Stinner98512272018-08-01 03:07:00 +0200367 'parser_debug': 0,
Victor Stinner56b29b62018-07-26 18:57:56 +0200368 'write_bytecode': 1,
369 'verbose': 0,
370 'quiet': 0,
371 'user_site_directory': 1,
Victor Stinnercab5d072019-05-17 19:01:14 +0200372 'configure_c_stdio': 0,
Victor Stinner98512272018-08-01 03:07:00 +0200373 'buffered_stdio': 1,
Victor Stinnerc5989cd2018-08-29 19:32:47 +0200374
Victor Stinnera6537fb2018-11-26 11:54:12 +0100375 'stdio_encoding': GET_DEFAULT_CONFIG,
376 'stdio_errors': GET_DEFAULT_CONFIG,
Victor Stinner56b29b62018-07-26 18:57:56 +0200377
Victor Stinner62be7632019-03-01 13:10:14 +0100378 'skip_source_first_line': 0,
379 'run_command': None,
380 'run_module': None,
381 'run_filename': None,
382
Victor Stinner56b29b62018-07-26 18:57:56 +0200383 '_install_importlib': 1,
Victor Stinnercb9fbd32019-05-01 23:51:56 -0400384 'check_hash_pycs_mode': 'default',
Victor Stinner9ef5dca2019-05-16 17:38:16 +0200385 'pathconfig_warnings': 1,
386 '_init_main': 1,
Victor Stinner56b29b62018-07-26 18:57:56 +0200387 }
Victor Stinner01de89c2018-11-14 17:39:45 +0100388 if MS_WINDOWS:
Victor Stinner331a6a52019-05-27 16:39:22 +0200389 CONFIG_COMPAT.update({
Victor Stinner01de89c2018-11-14 17:39:45 +0100390 'legacy_windows_stdio': 0,
391 })
392
Victor Stinner331a6a52019-05-27 16:39:22 +0200393 CONFIG_PYTHON = dict(CONFIG_COMPAT,
Victor Stinner20e1e252019-05-23 04:12:27 +0200394 _config_init=API_PYTHON,
Victor Stinnerbab0db62019-05-18 03:21:27 +0200395 configure_c_stdio=1,
396 parse_argv=1,
397 )
Victor Stinner331a6a52019-05-27 16:39:22 +0200398 CONFIG_ISOLATED = dict(CONFIG_COMPAT,
Victor Stinner20e1e252019-05-23 04:12:27 +0200399 _config_init=API_ISOLATED,
Victor Stinnerbab0db62019-05-18 03:21:27 +0200400 isolated=1,
401 use_environment=0,
402 user_site_directory=0,
403 dev_mode=0,
404 install_signal_handlers=0,
405 use_hash_seed=0,
406 faulthandler=0,
407 tracemalloc=0,
408 pathconfig_warnings=0,
409 )
410 if MS_WINDOWS:
Victor Stinner331a6a52019-05-27 16:39:22 +0200411 CONFIG_ISOLATED['legacy_windows_stdio'] = 0
Victor Stinnerbab0db62019-05-18 03:21:27 +0200412
Victor Stinner01de89c2018-11-14 17:39:45 +0100413 # global config
414 DEFAULT_GLOBAL_CONFIG = {
415 'Py_HasFileSystemDefaultEncoding': 0,
416 'Py_HashRandomizationFlag': 1,
417 '_Py_HasFileSystemDefaultEncodeErrors': 0,
418 }
Victor Stinner1075d162019-03-25 23:19:57 +0100419 COPY_GLOBAL_PRE_CONFIG = [
Victor Stinner1075d162019-03-25 23:19:57 +0100420 ('Py_UTF8Mode', 'utf8_mode'),
421 ]
Victor Stinner01de89c2018-11-14 17:39:45 +0100422 COPY_GLOBAL_CONFIG = [
423 # Copy core config to global config for expected values
424 # True means that the core config value is inverted (0 => 1 and 1 => 0)
425 ('Py_BytesWarningFlag', 'bytes_warning'),
426 ('Py_DebugFlag', 'parser_debug'),
427 ('Py_DontWriteBytecodeFlag', 'write_bytecode', True),
428 ('Py_FileSystemDefaultEncodeErrors', 'filesystem_errors'),
429 ('Py_FileSystemDefaultEncoding', 'filesystem_encoding'),
Victor Stinner9ef5dca2019-05-16 17:38:16 +0200430 ('Py_FrozenFlag', 'pathconfig_warnings', True),
Victor Stinner20004952019-03-26 02:31:11 +0100431 ('Py_IgnoreEnvironmentFlag', 'use_environment', True),
Victor Stinner01de89c2018-11-14 17:39:45 +0100432 ('Py_InspectFlag', 'inspect'),
433 ('Py_InteractiveFlag', 'interactive'),
Victor Stinner20004952019-03-26 02:31:11 +0100434 ('Py_IsolatedFlag', 'isolated'),
Victor Stinner01de89c2018-11-14 17:39:45 +0100435 ('Py_NoSiteFlag', 'site_import', True),
436 ('Py_NoUserSiteDirectory', 'user_site_directory', True),
437 ('Py_OptimizeFlag', 'optimization_level'),
438 ('Py_QuietFlag', 'quiet'),
Victor Stinner01de89c2018-11-14 17:39:45 +0100439 ('Py_UnbufferedStdioFlag', 'buffered_stdio', True),
440 ('Py_VerboseFlag', 'verbose'),
441 ]
442 if MS_WINDOWS:
Victor Stinner1075d162019-03-25 23:19:57 +0100443 COPY_GLOBAL_PRE_CONFIG.extend((
Victor Stinner01de89c2018-11-14 17:39:45 +0100444 ('Py_LegacyWindowsFSEncodingFlag', 'legacy_windows_fs_encoding'),
Victor Stinner1075d162019-03-25 23:19:57 +0100445 ))
446 COPY_GLOBAL_CONFIG.extend((
Victor Stinner01de89c2018-11-14 17:39:45 +0100447 ('Py_LegacyWindowsStdioFlag', 'legacy_windows_stdio'),
448 ))
Victor Stinner56b29b62018-07-26 18:57:56 +0200449
Victor Stinner425717f2019-05-20 16:38:48 +0200450 EXPECTED_CONFIG = None
451
Victor Stinner01de89c2018-11-14 17:39:45 +0100452 def main_xoptions(self, xoptions_list):
453 xoptions = {}
454 for opt in xoptions_list:
455 if '=' in opt:
456 key, value = opt.split('=', 1)
457 xoptions[key] = value
458 else:
459 xoptions[opt] = True
460 return xoptions
Victor Stinnerdfe0dc72018-08-29 11:47:29 +0200461
Victor Stinner425717f2019-05-20 16:38:48 +0200462 def _get_expected_config(self, env):
Victor Stinnera6537fb2018-11-26 11:54:12 +0100463 code = textwrap.dedent('''
464 import json
Victor Stinnera6537fb2018-11-26 11:54:12 +0100465 import sys
Victor Stinner5eb8b072019-05-15 02:12:48 +0200466 import _testinternalcapi
Victor Stinnera6537fb2018-11-26 11:54:12 +0100467
Victor Stinner5eb8b072019-05-15 02:12:48 +0200468 configs = _testinternalcapi.get_configs()
Victor Stinnera6537fb2018-11-26 11:54:12 +0100469
Victor Stinner425717f2019-05-20 16:38:48 +0200470 data = json.dumps(configs)
Victor Stinnera6537fb2018-11-26 11:54:12 +0100471 data = data.encode('utf-8')
472 sys.stdout.buffer.write(data)
473 sys.stdout.buffer.flush()
474 ''')
475
476 # Use -S to not import the site module: get the proper configuration
477 # when test_embed is run from a venv (bpo-35313)
Victor Stinner5eb8b072019-05-15 02:12:48 +0200478 args = [sys.executable, '-S', '-c', code]
Victor Stinnera6537fb2018-11-26 11:54:12 +0100479 proc = subprocess.run(args, env=env,
480 stdout=subprocess.PIPE,
481 stderr=subprocess.STDOUT)
482 if proc.returncode:
483 raise Exception(f"failed to get the default config: "
484 f"stdout={proc.stdout!r} stderr={proc.stderr!r}")
485 stdout = proc.stdout.decode('utf-8')
Victor Stinner4631da12019-05-02 15:30:21 -0400486 try:
Victor Stinner425717f2019-05-20 16:38:48 +0200487 return json.loads(stdout)
Victor Stinner4631da12019-05-02 15:30:21 -0400488 except json.JSONDecodeError:
489 self.fail(f"fail to decode stdout: {stdout!r}")
Victor Stinnera6537fb2018-11-26 11:54:12 +0100490
Victor Stinner425717f2019-05-20 16:38:48 +0200491 def get_expected_config(self, expected_preconfig, expected, env, api,
492 add_path=None):
493 cls = self.__class__
494 if cls.EXPECTED_CONFIG is None:
495 cls.EXPECTED_CONFIG = self._get_expected_config(env)
496 configs = {key: dict(value)
497 for key, value in self.EXPECTED_CONFIG.items()}
498
499 pre_config = configs['pre_config']
500 for key, value in expected_preconfig.items():
501 if value is self.GET_DEFAULT_CONFIG:
502 expected_preconfig[key] = pre_config[key]
503
Victor Stinner022be022019-05-22 23:58:50 +0200504 if not expected_preconfig['configure_locale'] or api == API_COMPAT:
Victor Stinner425717f2019-05-20 16:38:48 +0200505 # there is no easy way to get the locale encoding before
506 # setlocale(LC_CTYPE, "") is called: don't test encodings
507 for key in ('filesystem_encoding', 'filesystem_errors',
508 'stdio_encoding', 'stdio_errors'):
509 expected[key] = self.IGNORE_CONFIG
510
511 if not expected_preconfig['configure_locale']:
512 # UTF-8 Mode depends on the locale. There is no easy way
513 # to guess if UTF-8 Mode will be enabled or not if the locale
514 # is not configured.
515 expected_preconfig['utf8_mode'] = self.IGNORE_CONFIG
516
517 if expected_preconfig['utf8_mode'] == 1:
518 if expected['filesystem_encoding'] is self.GET_DEFAULT_CONFIG:
519 expected['filesystem_encoding'] = 'utf-8'
520 if expected['filesystem_errors'] is self.GET_DEFAULT_CONFIG:
521 expected['filesystem_errors'] = self.UTF8_MODE_ERRORS
522 if expected['stdio_encoding'] is self.GET_DEFAULT_CONFIG:
523 expected['stdio_encoding'] = 'utf-8'
524 if expected['stdio_errors'] is self.GET_DEFAULT_CONFIG:
525 expected['stdio_errors'] = 'surrogateescape'
526
Victor Stinner91c99872019-05-14 22:01:51 +0200527 if expected['executable'] is self.GET_DEFAULT_CONFIG:
528 if sys.platform == 'win32':
529 expected['executable'] = self.test_exe
530 else:
531 if expected['program_name'] is not self.GET_DEFAULT_CONFIG:
532 expected['executable'] = os.path.abspath(expected['program_name'])
533 else:
534 expected['executable'] = os.path.join(os.getcwd(), '_testembed')
535 if expected['program_name'] is self.GET_DEFAULT_CONFIG:
536 expected['program_name'] = './_testembed'
537
Victor Stinner331a6a52019-05-27 16:39:22 +0200538 config = configs['config']
Victor Stinnera6537fb2018-11-26 11:54:12 +0100539 for key, value in expected.items():
540 if value is self.GET_DEFAULT_CONFIG:
Victor Stinner331a6a52019-05-27 16:39:22 +0200541 expected[key] = config[key]
Victor Stinner5eb8b072019-05-15 02:12:48 +0200542
Victor Stinner331a6a52019-05-27 16:39:22 +0200543 prepend_path = expected['pythonpath_env']
Victor Stinner425717f2019-05-20 16:38:48 +0200544 if prepend_path is not None:
545 expected['module_search_paths'] = [prepend_path, *expected['module_search_paths']]
Victor Stinner5eb8b072019-05-15 02:12:48 +0200546 if add_path is not None:
Victor Stinner425717f2019-05-20 16:38:48 +0200547 expected['module_search_paths'] = [*expected['module_search_paths'], add_path]
Victor Stinnerbcfbbd72019-05-17 22:44:16 +0200548
Victor Stinner425717f2019-05-20 16:38:48 +0200549 for key in self.COPY_PRE_CONFIG:
550 if key not in expected_preconfig:
551 expected_preconfig[key] = expected[key]
Victor Stinner01de89c2018-11-14 17:39:45 +0100552
Victor Stinner331a6a52019-05-27 16:39:22 +0200553 def check_pre_config(self, configs, expected):
554 pre_config = dict(configs['pre_config'])
Victor Stinner425717f2019-05-20 16:38:48 +0200555 for key, value in list(expected.items()):
556 if value is self.IGNORE_CONFIG:
557 del pre_config[key]
558 del expected[key]
559 self.assertEqual(pre_config, expected)
Victor Stinner1075d162019-03-25 23:19:57 +0100560
Victor Stinner331a6a52019-05-27 16:39:22 +0200561 def check_config(self, configs, expected):
562 config = dict(configs['config'])
Victor Stinnerbcfbbd72019-05-17 22:44:16 +0200563 for key, value in list(expected.items()):
564 if value is self.IGNORE_CONFIG:
Victor Stinner331a6a52019-05-27 16:39:22 +0200565 del config[key]
Victor Stinnerbcfbbd72019-05-17 22:44:16 +0200566 del expected[key]
Victor Stinner331a6a52019-05-27 16:39:22 +0200567 self.assertEqual(config, expected)
Victor Stinnerdfe0dc72018-08-29 11:47:29 +0200568
Victor Stinner331a6a52019-05-27 16:39:22 +0200569 def check_global_config(self, configs):
570 pre_config = configs['pre_config']
571 config = configs['config']
Victor Stinner00b137c2018-11-13 19:59:26 +0100572
Victor Stinnera6537fb2018-11-26 11:54:12 +0100573 expected = dict(self.DEFAULT_GLOBAL_CONFIG)
Victor Stinner01de89c2018-11-14 17:39:45 +0100574 for item in self.COPY_GLOBAL_CONFIG:
Victor Stinner7ddd56f2018-11-14 00:24:28 +0100575 if len(item) == 3:
576 global_key, core_key, opposite = item
Victor Stinner331a6a52019-05-27 16:39:22 +0200577 expected[global_key] = 0 if config[core_key] else 1
Victor Stinner7ddd56f2018-11-14 00:24:28 +0100578 else:
579 global_key, core_key = item
Victor Stinner331a6a52019-05-27 16:39:22 +0200580 expected[global_key] = config[core_key]
Victor Stinner1075d162019-03-25 23:19:57 +0100581 for item in self.COPY_GLOBAL_PRE_CONFIG:
582 if len(item) == 3:
583 global_key, core_key, opposite = item
584 expected[global_key] = 0 if pre_config[core_key] else 1
585 else:
586 global_key, core_key = item
587 expected[global_key] = pre_config[core_key]
Victor Stinner7ddd56f2018-11-14 00:24:28 +0100588
Victor Stinner331a6a52019-05-27 16:39:22 +0200589 self.assertEqual(configs['global_config'], expected)
Victor Stinner7ddd56f2018-11-14 00:24:28 +0100590
Victor Stinner331a6a52019-05-27 16:39:22 +0200591 def check_all_configs(self, testname, expected_config=None,
Victor Stinner022be022019-05-22 23:58:50 +0200592 expected_preconfig=None, add_path=None, stderr=None,
593 *, api):
Victor Stinner01de89c2018-11-14 17:39:45 +0100594 env = dict(os.environ)
595 # Remove PYTHON* environment variables to get deterministic environment
596 for key in list(env):
597 if key.startswith('PYTHON'):
598 del env[key]
Victor Stinner01de89c2018-11-14 17:39:45 +0100599
Victor Stinner022be022019-05-22 23:58:50 +0200600 if api == API_ISOLATED:
601 default_preconfig = self.PRE_CONFIG_ISOLATED
602 elif api == API_PYTHON:
603 default_preconfig = self.PRE_CONFIG_PYTHON
Victor Stinnerbab0db62019-05-18 03:21:27 +0200604 else:
Victor Stinner022be022019-05-22 23:58:50 +0200605 default_preconfig = self.PRE_CONFIG_COMPAT
Victor Stinnerbab0db62019-05-18 03:21:27 +0200606 if expected_preconfig is None:
607 expected_preconfig = {}
608 expected_preconfig = dict(default_preconfig, **expected_preconfig)
609 if expected_config is None:
610 expected_config = {}
Victor Stinner425717f2019-05-20 16:38:48 +0200611
Victor Stinner022be022019-05-22 23:58:50 +0200612 if api == API_PYTHON:
Victor Stinner331a6a52019-05-27 16:39:22 +0200613 default_config = self.CONFIG_PYTHON
Victor Stinner022be022019-05-22 23:58:50 +0200614 elif api == API_ISOLATED:
Victor Stinner331a6a52019-05-27 16:39:22 +0200615 default_config = self.CONFIG_ISOLATED
Victor Stinner425717f2019-05-20 16:38:48 +0200616 else:
Victor Stinner331a6a52019-05-27 16:39:22 +0200617 default_config = self.CONFIG_COMPAT
Victor Stinner425717f2019-05-20 16:38:48 +0200618 expected_config = dict(default_config, **expected_config)
Victor Stinner425717f2019-05-20 16:38:48 +0200619
620 self.get_expected_config(expected_preconfig,
621 expected_config, env,
622 api, add_path)
Victor Stinner1075d162019-03-25 23:19:57 +0100623
Victor Stinner9ef5dca2019-05-16 17:38:16 +0200624 out, err = self.run_embedded_interpreter(testname, env=env)
625 if stderr is None and not expected_config['verbose']:
626 stderr = ""
627 if stderr is not None:
628 self.assertEqual(err.rstrip(), stderr)
629 try:
Victor Stinner331a6a52019-05-27 16:39:22 +0200630 configs = json.loads(out)
Victor Stinner9ef5dca2019-05-16 17:38:16 +0200631 except json.JSONDecodeError:
632 self.fail(f"fail to decode stdout: {out!r}")
633
Victor Stinner331a6a52019-05-27 16:39:22 +0200634 self.check_pre_config(configs, expected_preconfig)
635 self.check_config(configs, expected_config)
636 self.check_global_config(configs)
Victor Stinner7ddd56f2018-11-14 00:24:28 +0100637
Victor Stinner56b29b62018-07-26 18:57:56 +0200638 def test_init_default_config(self):
Victor Stinner331a6a52019-05-27 16:39:22 +0200639 self.check_all_configs("test_init_initialize_config", api=API_COMPAT)
Victor Stinner022be022019-05-22 23:58:50 +0200640
641 def test_preinit_compat_config(self):
Victor Stinner331a6a52019-05-27 16:39:22 +0200642 self.check_all_configs("test_preinit_compat_config", api=API_COMPAT)
Victor Stinner022be022019-05-22 23:58:50 +0200643
644 def test_init_compat_config(self):
Victor Stinner331a6a52019-05-27 16:39:22 +0200645 self.check_all_configs("test_init_compat_config", api=API_COMPAT)
Victor Stinner56b29b62018-07-26 18:57:56 +0200646
647 def test_init_global_config(self):
Victor Stinner1075d162019-03-25 23:19:57 +0100648 preconfig = {
649 'utf8_mode': 1,
650 }
Victor Stinner56b29b62018-07-26 18:57:56 +0200651 config = {
652 'program_name': './globalvar',
653 'site_import': 0,
654 'bytes_warning': 1,
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100655 'warnoptions': ['default::BytesWarning'],
Victor Stinner56b29b62018-07-26 18:57:56 +0200656 'inspect': 1,
657 'interactive': 1,
658 'optimization_level': 2,
659 'write_bytecode': 0,
660 'verbose': 1,
661 'quiet': 1,
Victor Stinner98512272018-08-01 03:07:00 +0200662 'buffered_stdio': 0,
Victor Stinnerdfe0dc72018-08-29 11:47:29 +0200663
Victor Stinner56b29b62018-07-26 18:57:56 +0200664 'user_site_directory': 0,
Victor Stinner54b43bb2019-05-16 18:30:15 +0200665 'pathconfig_warnings': 0,
Victor Stinner56b29b62018-07-26 18:57:56 +0200666 }
Victor Stinner331a6a52019-05-27 16:39:22 +0200667 self.check_all_configs("test_init_global_config", config, preconfig,
668 api=API_COMPAT)
Victor Stinner56b29b62018-07-26 18:57:56 +0200669
670 def test_init_from_config(self):
Victor Stinner1075d162019-03-25 23:19:57 +0100671 preconfig = {
Victor Stinnerb16b4e42019-05-17 15:20:52 +0200672 'allocator': PYMEM_ALLOCATOR_MALLOC,
Victor Stinner1075d162019-03-25 23:19:57 +0100673 'utf8_mode': 1,
674 }
Victor Stinner56b29b62018-07-26 18:57:56 +0200675 config = {
676 'install_signal_handlers': 0,
677 'use_hash_seed': 1,
678 'hash_seed': 123,
Victor Stinner56b29b62018-07-26 18:57:56 +0200679 'tracemalloc': 2,
680 'import_time': 1,
681 'show_ref_count': 1,
682 'show_alloc_count': 1,
683 'malloc_stats': 1,
684
Victor Stinnerdfe0dc72018-08-29 11:47:29 +0200685 'stdio_encoding': 'iso8859-1',
686 'stdio_errors': 'replace',
Victor Stinner56b29b62018-07-26 18:57:56 +0200687
688 'pycache_prefix': 'conf_pycache_prefix',
689 'program_name': './conf_program_name',
Victor Stinner2f549082019-03-29 15:13:46 +0100690 'argv': ['-c', 'arg2'],
Victor Stinnercab5d072019-05-17 19:01:14 +0200691 'parse_argv': 1,
Victor Stinner331a6a52019-05-27 16:39:22 +0200692 'xoptions': ['xoption1=3', 'xoption2=', 'xoption3'],
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100693 'warnoptions': ['error::ResourceWarning', 'default::BytesWarning'],
Victor Stinner2f549082019-03-29 15:13:46 +0100694 'run_command': 'pass\n',
Victor Stinner56b29b62018-07-26 18:57:56 +0200695
696 'site_import': 0,
697 'bytes_warning': 1,
698 'inspect': 1,
699 'interactive': 1,
700 'optimization_level': 2,
701 'write_bytecode': 0,
702 'verbose': 1,
703 'quiet': 1,
Victor Stinnercab5d072019-05-17 19:01:14 +0200704 'configure_c_stdio': 1,
Victor Stinner98512272018-08-01 03:07:00 +0200705 'buffered_stdio': 0,
Victor Stinner56b29b62018-07-26 18:57:56 +0200706 'user_site_directory': 0,
707 'faulthandler': 1,
Victor Stinnerb75d7e22018-08-01 02:13:04 +0200708
Victor Stinnercb9fbd32019-05-01 23:51:56 -0400709 'check_hash_pycs_mode': 'always',
Victor Stinner54b43bb2019-05-16 18:30:15 +0200710 'pathconfig_warnings': 0,
Victor Stinner56b29b62018-07-26 18:57:56 +0200711 }
Victor Stinner331a6a52019-05-27 16:39:22 +0200712 self.check_all_configs("test_init_from_config", config, preconfig,
713 api=API_COMPAT)
Victor Stinner56b29b62018-07-26 18:57:56 +0200714
Victor Stinner20e1e252019-05-23 04:12:27 +0200715 def test_init_compat_env(self):
716 preconfig = {
717 'allocator': PYMEM_ALLOCATOR_MALLOC,
718 }
719 config = {
720 'use_hash_seed': 1,
721 'hash_seed': 42,
722 'tracemalloc': 2,
723 'import_time': 1,
724 'malloc_stats': 1,
725 'inspect': 1,
726 'optimization_level': 2,
Victor Stinner331a6a52019-05-27 16:39:22 +0200727 'pythonpath_env': '/my/path',
Victor Stinner20e1e252019-05-23 04:12:27 +0200728 'pycache_prefix': 'env_pycache_prefix',
729 'write_bytecode': 0,
730 'verbose': 1,
731 'buffered_stdio': 0,
732 'stdio_encoding': 'iso8859-1',
733 'stdio_errors': 'replace',
734 'user_site_directory': 0,
735 'faulthandler': 1,
736 'warnoptions': ['EnvVar'],
737 }
Victor Stinner331a6a52019-05-27 16:39:22 +0200738 self.check_all_configs("test_init_compat_env", config, preconfig,
739 api=API_COMPAT)
Victor Stinner20e1e252019-05-23 04:12:27 +0200740
741 def test_init_python_env(self):
Victor Stinner425717f2019-05-20 16:38:48 +0200742 preconfig = {
743 'allocator': PYMEM_ALLOCATOR_MALLOC,
Victor Stinner022be022019-05-22 23:58:50 +0200744 'utf8_mode': 1,
Victor Stinner425717f2019-05-20 16:38:48 +0200745 }
746 config = {
747 'use_hash_seed': 1,
748 'hash_seed': 42,
749 'tracemalloc': 2,
750 'import_time': 1,
751 'malloc_stats': 1,
752 'inspect': 1,
753 'optimization_level': 2,
Victor Stinner331a6a52019-05-27 16:39:22 +0200754 'pythonpath_env': '/my/path',
Victor Stinner425717f2019-05-20 16:38:48 +0200755 'pycache_prefix': 'env_pycache_prefix',
756 'write_bytecode': 0,
757 'verbose': 1,
758 'buffered_stdio': 0,
759 'stdio_encoding': 'iso8859-1',
760 'stdio_errors': 'replace',
761 'user_site_directory': 0,
762 'faulthandler': 1,
763 'warnoptions': ['EnvVar'],
764 }
Victor Stinner331a6a52019-05-27 16:39:22 +0200765 self.check_all_configs("test_init_python_env", config, preconfig,
766 api=API_PYTHON)
Victor Stinnerb35be4b2019-03-05 17:37:44 +0100767
768 def test_init_env_dev_mode(self):
Victor Stinner425717f2019-05-20 16:38:48 +0200769 preconfig = dict(allocator=PYMEM_ALLOCATOR_DEBUG)
770 config = dict(dev_mode=1,
771 faulthandler=1,
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100772 warnoptions=['default'])
Victor Stinner331a6a52019-05-27 16:39:22 +0200773 self.check_all_configs("test_init_env_dev_mode", config, preconfig,
774 api=API_COMPAT)
Victor Stinner56b29b62018-07-26 18:57:56 +0200775
Victor Stinner20004952019-03-26 02:31:11 +0100776 def test_init_env_dev_mode_alloc(self):
Victor Stinner425717f2019-05-20 16:38:48 +0200777 preconfig = dict(allocator=PYMEM_ALLOCATOR_MALLOC)
778 config = dict(dev_mode=1,
779 faulthandler=1,
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100780 warnoptions=['default'])
Victor Stinner331a6a52019-05-27 16:39:22 +0200781 self.check_all_configs("test_init_env_dev_mode_alloc", config, preconfig,
782 api=API_COMPAT)
Victor Stinner25d13f32019-03-06 12:51:53 +0100783
Victor Stinner56b29b62018-07-26 18:57:56 +0200784 def test_init_dev_mode(self):
Victor Stinner1075d162019-03-25 23:19:57 +0100785 preconfig = {
Victor Stinnerb16b4e42019-05-17 15:20:52 +0200786 'allocator': PYMEM_ALLOCATOR_DEBUG,
Victor Stinner56b29b62018-07-26 18:57:56 +0200787 }
Victor Stinner1075d162019-03-25 23:19:57 +0100788 config = {
789 'faulthandler': 1,
Victor Stinner20004952019-03-26 02:31:11 +0100790 'dev_mode': 1,
Victor Stinnerf8ba6f52019-03-26 16:58:50 +0100791 'warnoptions': ['default'],
Victor Stinner1075d162019-03-25 23:19:57 +0100792 }
Victor Stinner331a6a52019-05-27 16:39:22 +0200793 self.check_all_configs("test_init_dev_mode", config, preconfig,
794 api=API_PYTHON)
Victor Stinner6d1c4672019-05-20 11:02:00 +0200795
796 def test_preinit_parse_argv(self):
797 # Pre-initialize implicitly using argv: make sure that -X dev
798 # is used to configure the allocation in preinitialization
799 preconfig = {
800 'allocator': PYMEM_ALLOCATOR_DEBUG,
801 }
802 config = {
803 'argv': ['script.py'],
804 'run_filename': 'script.py',
805 'dev_mode': 1,
806 'faulthandler': 1,
807 'warnoptions': ['default'],
808 'xoptions': ['dev'],
809 }
Victor Stinner331a6a52019-05-27 16:39:22 +0200810 self.check_all_configs("test_preinit_parse_argv", config, preconfig,
811 api=API_PYTHON)
Victor Stinner6d1c4672019-05-20 11:02:00 +0200812
813 def test_preinit_dont_parse_argv(self):
814 # -X dev must be ignored by isolated preconfiguration
815 preconfig = {
816 'isolated': 0,
817 }
818 config = {
819 'argv': ["python3", "-E", "-I",
820 "-X", "dev", "-X", "utf8", "script.py"],
821 'isolated': 0,
822 }
Victor Stinner331a6a52019-05-27 16:39:22 +0200823 self.check_all_configs("test_preinit_dont_parse_argv", config, preconfig,
824 api=API_ISOLATED)
Victor Stinner56b29b62018-07-26 18:57:56 +0200825
Victor Stinnercab5d072019-05-17 19:01:14 +0200826 def test_init_isolated_flag(self):
Victor Stinner1075d162019-03-25 23:19:57 +0100827 config = {
Victor Stinner20004952019-03-26 02:31:11 +0100828 'isolated': 1,
829 'use_environment': 0,
Victor Stinner56b29b62018-07-26 18:57:56 +0200830 'user_site_directory': 0,
831 }
Victor Stinner331a6a52019-05-27 16:39:22 +0200832 self.check_all_configs("test_init_isolated_flag", config, api=API_PYTHON)
Victor Stinner56b29b62018-07-26 18:57:56 +0200833
Victor Stinner6da20a42019-03-27 00:26:18 +0100834 def test_preinit_isolated1(self):
835 # _PyPreConfig.isolated=1, _PyCoreConfig.isolated not set
Victor Stinner6da20a42019-03-27 00:26:18 +0100836 config = {
837 'isolated': 1,
838 'use_environment': 0,
839 'user_site_directory': 0,
840 }
Victor Stinner331a6a52019-05-27 16:39:22 +0200841 self.check_all_configs("test_preinit_isolated1", config, api=API_COMPAT)
Victor Stinner6da20a42019-03-27 00:26:18 +0100842
843 def test_preinit_isolated2(self):
844 # _PyPreConfig.isolated=0, _PyCoreConfig.isolated=1
Victor Stinner6da20a42019-03-27 00:26:18 +0100845 config = {
846 'isolated': 1,
847 'use_environment': 0,
848 'user_site_directory': 0,
849 }
Victor Stinner331a6a52019-05-27 16:39:22 +0200850 self.check_all_configs("test_preinit_isolated2", config, api=API_COMPAT)
Victor Stinner6da20a42019-03-27 00:26:18 +0100851
Victor Stinner6d1c4672019-05-20 11:02:00 +0200852 def test_preinit_isolated_config(self):
Victor Stinner331a6a52019-05-27 16:39:22 +0200853 self.check_all_configs("test_preinit_isolated_config", api=API_ISOLATED)
Victor Stinner6d1c4672019-05-20 11:02:00 +0200854
Victor Stinnercab5d072019-05-17 19:01:14 +0200855 def test_init_isolated_config(self):
Victor Stinner331a6a52019-05-27 16:39:22 +0200856 self.check_all_configs("test_init_isolated_config", api=API_ISOLATED)
Victor Stinner5edcf262019-05-23 00:57:57 +0200857
858 def test_preinit_python_config(self):
Victor Stinner331a6a52019-05-27 16:39:22 +0200859 self.check_all_configs("test_preinit_python_config", api=API_PYTHON)
Victor Stinnercab5d072019-05-17 19:01:14 +0200860
861 def test_init_python_config(self):
Victor Stinner331a6a52019-05-27 16:39:22 +0200862 self.check_all_configs("test_init_python_config", api=API_PYTHON)
Victor Stinnercab5d072019-05-17 19:01:14 +0200863
Victor Stinnerbcfbbd72019-05-17 22:44:16 +0200864 def test_init_dont_configure_locale(self):
865 # _PyPreConfig.configure_locale=0
866 preconfig = {
867 'configure_locale': 0,
Victor Stinner425717f2019-05-20 16:38:48 +0200868 'coerce_c_locale': 0,
Victor Stinnerbcfbbd72019-05-17 22:44:16 +0200869 }
Victor Stinner331a6a52019-05-27 16:39:22 +0200870 self.check_all_configs("test_init_dont_configure_locale", {}, preconfig,
871 api=API_PYTHON)
Victor Stinnerbcfbbd72019-05-17 22:44:16 +0200872
Victor Stinner91c99872019-05-14 22:01:51 +0200873 def test_init_read_set(self):
Victor Stinner331a6a52019-05-27 16:39:22 +0200874 config = {
Victor Stinner91c99872019-05-14 22:01:51 +0200875 'program_name': './init_read_set',
876 'executable': 'my_executable',
877 }
Victor Stinner331a6a52019-05-27 16:39:22 +0200878 self.check_all_configs("test_init_read_set", config,
879 api=API_PYTHON,
880 add_path="init_read_set_path")
Victor Stinner91c99872019-05-14 22:01:51 +0200881
Victor Stinner9ef5dca2019-05-16 17:38:16 +0200882 def test_init_run_main(self):
Victor Stinner5eb8b072019-05-15 02:12:48 +0200883 code = ('import _testinternalcapi, json; '
884 'print(json.dumps(_testinternalcapi.get_configs()))')
Victor Stinner331a6a52019-05-27 16:39:22 +0200885 config = {
Victor Stinner5eb8b072019-05-15 02:12:48 +0200886 'argv': ['-c', 'arg2'],
Victor Stinner5eb8b072019-05-15 02:12:48 +0200887 'program_name': './python3',
888 'run_command': code + '\n',
Victor Stinnercab5d072019-05-17 19:01:14 +0200889 'parse_argv': 1,
Victor Stinner5eb8b072019-05-15 02:12:48 +0200890 }
Victor Stinner331a6a52019-05-27 16:39:22 +0200891 self.check_all_configs("test_init_run_main", config, api=API_PYTHON)
Victor Stinner9ef5dca2019-05-16 17:38:16 +0200892
893 def test_init_main(self):
Victor Stinner9ef5dca2019-05-16 17:38:16 +0200894 code = ('import _testinternalcapi, json; '
895 'print(json.dumps(_testinternalcapi.get_configs()))')
Victor Stinner331a6a52019-05-27 16:39:22 +0200896 config = {
Victor Stinner9ef5dca2019-05-16 17:38:16 +0200897 'argv': ['-c', 'arg2'],
Victor Stinner9ef5dca2019-05-16 17:38:16 +0200898 'program_name': './python3',
899 'run_command': code + '\n',
Victor Stinnercab5d072019-05-17 19:01:14 +0200900 'parse_argv': 1,
Victor Stinner9ef5dca2019-05-16 17:38:16 +0200901 '_init_main': 0,
902 }
Victor Stinner331a6a52019-05-27 16:39:22 +0200903 self.check_all_configs("test_init_main", config,
904 api=API_PYTHON,
905 stderr="Run Python code before _Py_InitializeMain")
Victor Stinner5eb8b072019-05-15 02:12:48 +0200906
Victor Stinnercab5d072019-05-17 19:01:14 +0200907 def test_init_parse_argv(self):
Victor Stinner331a6a52019-05-27 16:39:22 +0200908 config = {
Victor Stinnerbab0db62019-05-18 03:21:27 +0200909 'parse_argv': 1,
Victor Stinnercab5d072019-05-17 19:01:14 +0200910 'argv': ['-c', 'arg1', '-v', 'arg3'],
911 'program_name': './argv0',
Victor Stinnercab5d072019-05-17 19:01:14 +0200912 'run_command': 'pass\n',
913 'use_environment': 0,
914 }
Victor Stinner331a6a52019-05-27 16:39:22 +0200915 self.check_all_configs("test_init_parse_argv", config, api=API_PYTHON)
Victor Stinnercab5d072019-05-17 19:01:14 +0200916
Victor Stinnerae239f62019-05-16 17:02:56 +0200917 def test_init_dont_parse_argv(self):
Victor Stinner6d1c4672019-05-20 11:02:00 +0200918 pre_config = {
919 'parse_argv': 0,
920 }
Victor Stinner331a6a52019-05-27 16:39:22 +0200921 config = {
Victor Stinnerbab0db62019-05-18 03:21:27 +0200922 'parse_argv': 0,
Victor Stinnercab5d072019-05-17 19:01:14 +0200923 'argv': ['./argv0', '-E', '-c', 'pass', 'arg1', '-v', 'arg3'],
924 'program_name': './argv0',
Victor Stinnerae239f62019-05-16 17:02:56 +0200925 }
Victor Stinner331a6a52019-05-27 16:39:22 +0200926 self.check_all_configs("test_init_dont_parse_argv", config, pre_config,
927 api=API_PYTHON)
Victor Stinnerae239f62019-05-16 17:02:56 +0200928
Victor Stinner56b29b62018-07-26 18:57:56 +0200929
Steve Dowerb82e17e2019-05-23 08:45:22 -0700930class AuditingTests(EmbeddingTestsMixin, unittest.TestCase):
931 def test_open_code_hook(self):
932 self.run_embedded_interpreter("test_open_code_hook")
933
934 def test_audit(self):
935 self.run_embedded_interpreter("test_audit")
936
937 def test_audit_subinterpreter(self):
938 self.run_embedded_interpreter("test_audit_subinterpreter")
939
940
Nick Coghlan39f0bb52017-11-28 08:11:51 +1000941if __name__ == "__main__":
942 unittest.main()