blob: e6c8c8070b8664d8f5e639ff9b1005f58e62dc41 [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 Stinner35c28d52018-11-14 02:01:52 +01006import json
Nick Coghlan39f0bb52017-11-28 08:11:51 +10007import os
8import re
9import subprocess
10import sys
11
12
Victor Stinner9ee1d422018-11-14 18:58:01 +010013MS_WINDOWS = (os.name == 'nt')
14
15
Victor Stinner0c90d6f2018-08-05 12:31:59 +020016class EmbeddingTestsMixin:
Nick Coghlan39f0bb52017-11-28 08:11:51 +100017 def setUp(self):
18 here = os.path.abspath(__file__)
19 basepath = os.path.dirname(os.path.dirname(os.path.dirname(here)))
20 exename = "_testembed"
Victor Stinner9ee1d422018-11-14 18:58:01 +010021 if MS_WINDOWS:
Nick Coghlan39f0bb52017-11-28 08:11:51 +100022 ext = ("_d" if "_d" in sys.executable else "") + ".exe"
23 exename += ext
24 exepath = os.path.dirname(sys.executable)
25 else:
26 exepath = os.path.join(basepath, "Programs")
27 self.test_exe = exe = os.path.join(exepath, exename)
28 if not os.path.exists(exe):
29 self.skipTest("%r doesn't exist" % exe)
30 # This is needed otherwise we get a fatal error:
31 # "Py_Initialize: Unable to get the locale encoding
32 # LookupError: no codec search functions registered: can't find encoding"
33 self.oldcwd = os.getcwd()
34 os.chdir(basepath)
35
36 def tearDown(self):
37 os.chdir(self.oldcwd)
38
39 def run_embedded_interpreter(self, *args, env=None):
40 """Runs a test in the embedded interpreter"""
41 cmd = [self.test_exe]
42 cmd.extend(args)
Victor Stinner9ee1d422018-11-14 18:58:01 +010043 if env is not None and MS_WINDOWS:
Nick Coghlan39f0bb52017-11-28 08:11:51 +100044 # Windows requires at least the SYSTEMROOT environment variable to
45 # start Python.
46 env = env.copy()
47 env['SYSTEMROOT'] = os.environ['SYSTEMROOT']
48
49 p = subprocess.Popen(cmd,
50 stdout=subprocess.PIPE,
51 stderr=subprocess.PIPE,
52 universal_newlines=True,
53 env=env)
54 (out, err) = p.communicate()
55 if p.returncode != 0 and support.verbose:
56 print(f"--- {cmd} failed ---")
57 print(f"stdout:\n{out}")
Miss Islington (bot)c6d94c32018-03-25 04:27:57 -070058 print(f"stderr:\n{err}")
Nick Coghlan39f0bb52017-11-28 08:11:51 +100059 print(f"------")
60
61 self.assertEqual(p.returncode, 0,
62 "bad returncode %d, stderr is %r" %
63 (p.returncode, err))
64 return out, err
65
66 def run_repeated_init_and_subinterpreters(self):
67 out, err = self.run_embedded_interpreter("repeated_init_and_subinterpreters")
68 self.assertEqual(err, "")
69
70 # The output from _testembed looks like this:
71 # --- Pass 0 ---
72 # interp 0 <0x1cf9330>, thread state <0x1cf9700>: id(modules) = 139650431942728
73 # interp 1 <0x1d4f690>, thread state <0x1d35350>: id(modules) = 139650431165784
74 # interp 2 <0x1d5a690>, thread state <0x1d99ed0>: id(modules) = 139650413140368
75 # interp 3 <0x1d4f690>, thread state <0x1dc3340>: id(modules) = 139650412862200
76 # interp 0 <0x1cf9330>, thread state <0x1cf9700>: id(modules) = 139650431942728
77 # --- Pass 1 ---
78 # ...
79
80 interp_pat = (r"^interp (\d+) <(0x[\dA-F]+)>, "
81 r"thread state <(0x[\dA-F]+)>: "
82 r"id\(modules\) = ([\d]+)$")
83 Interp = namedtuple("Interp", "id interp tstate modules")
84
85 numloops = 0
86 current_run = []
87 for line in out.splitlines():
88 if line == "--- Pass {} ---".format(numloops):
89 self.assertEqual(len(current_run), 0)
Miss Islington (bot)c6d94c32018-03-25 04:27:57 -070090 if support.verbose > 1:
Nick Coghlan39f0bb52017-11-28 08:11:51 +100091 print(line)
92 numloops += 1
93 continue
94
95 self.assertLess(len(current_run), 5)
96 match = re.match(interp_pat, line)
97 if match is None:
98 self.assertRegex(line, interp_pat)
99
100 # Parse the line from the loop. The first line is the main
101 # interpreter and the 3 afterward are subinterpreters.
102 interp = Interp(*match.groups())
Miss Islington (bot)c6d94c32018-03-25 04:27:57 -0700103 if support.verbose > 1:
Nick Coghlan39f0bb52017-11-28 08:11:51 +1000104 print(interp)
105 self.assertTrue(interp.interp)
106 self.assertTrue(interp.tstate)
107 self.assertTrue(interp.modules)
108 current_run.append(interp)
109
110 # The last line in the loop should be the same as the first.
111 if len(current_run) == 5:
112 main = current_run[0]
113 self.assertEqual(interp, main)
114 yield current_run
115 current_run = []
116
Victor Stinner0c90d6f2018-08-05 12:31:59 +0200117
118class EmbeddingTests(EmbeddingTestsMixin, unittest.TestCase):
Nick Coghlan39f0bb52017-11-28 08:11:51 +1000119 def test_subinterps_main(self):
120 for run in self.run_repeated_init_and_subinterpreters():
121 main = run[0]
122
123 self.assertEqual(main.id, '0')
124
125 def test_subinterps_different_ids(self):
126 for run in self.run_repeated_init_and_subinterpreters():
127 main, *subs, _ = run
128
129 mainid = int(main.id)
130 for i, sub in enumerate(subs):
131 self.assertEqual(sub.id, str(mainid + i + 1))
132
133 def test_subinterps_distinct_state(self):
134 for run in self.run_repeated_init_and_subinterpreters():
135 main, *subs, _ = run
136
137 if '0x0' in main:
138 # XXX Fix on Windows (and other platforms): something
139 # is going on with the pointers in Programs/_testembed.c.
140 # interp.interp is 0x0 and interp.modules is the same
141 # between interpreters.
142 raise unittest.SkipTest('platform prints pointers as 0x0')
143
144 for sub in subs:
145 # A new subinterpreter may have the same
146 # PyInterpreterState pointer as a previous one if
147 # the earlier one has already been destroyed. So
148 # we compare with the main interpreter. The same
149 # applies to tstate.
150 self.assertNotEqual(sub.interp, main.interp)
151 self.assertNotEqual(sub.tstate, main.tstate)
152 self.assertNotEqual(sub.modules, main.modules)
153
154 def test_forced_io_encoding(self):
155 # Checks forced configuration of embedded interpreter IO streams
156 env = dict(os.environ, PYTHONIOENCODING="utf-8:surrogateescape")
157 out, err = self.run_embedded_interpreter("forced_io_encoding", env=env)
158 if support.verbose > 1:
159 print()
160 print(out)
161 print(err)
162 expected_stream_encoding = "utf-8"
163 expected_errors = "surrogateescape"
164 expected_output = '\n'.join([
165 "--- Use defaults ---",
166 "Expected encoding: default",
167 "Expected errors: default",
168 "stdin: {in_encoding}:{errors}",
169 "stdout: {out_encoding}:{errors}",
170 "stderr: {out_encoding}:backslashreplace",
171 "--- Set errors only ---",
172 "Expected encoding: default",
173 "Expected errors: ignore",
174 "stdin: {in_encoding}:ignore",
175 "stdout: {out_encoding}:ignore",
176 "stderr: {out_encoding}:backslashreplace",
177 "--- Set encoding only ---",
178 "Expected encoding: latin-1",
179 "Expected errors: default",
180 "stdin: latin-1:{errors}",
181 "stdout: latin-1:{errors}",
182 "stderr: latin-1:backslashreplace",
183 "--- Set encoding and errors ---",
184 "Expected encoding: latin-1",
185 "Expected errors: replace",
186 "stdin: latin-1:replace",
187 "stdout: latin-1:replace",
188 "stderr: latin-1:backslashreplace"])
189 expected_output = expected_output.format(
190 in_encoding=expected_stream_encoding,
191 out_encoding=expected_stream_encoding,
192 errors=expected_errors)
193 # This is useful if we ever trip over odd platform behaviour
194 self.maxDiff = None
195 self.assertEqual(out.strip(), expected_output)
196
197 def test_pre_initialization_api(self):
198 """
Miss Islington (bot)c6d94c32018-03-25 04:27:57 -0700199 Checks some key parts of the C-API that need to work before the runtine
Nick Coghlan39f0bb52017-11-28 08:11:51 +1000200 is initialized (via Py_Initialize()).
201 """
202 env = dict(os.environ, PYTHONPATH=os.pathsep.join(sys.path))
203 out, err = self.run_embedded_interpreter("pre_initialization_api", env=env)
Victor Stinner9ee1d422018-11-14 18:58:01 +0100204 if MS_WINDOWS:
Miss Islington (bot)c6d94c32018-03-25 04:27:57 -0700205 expected_path = self.test_exe
206 else:
207 expected_path = os.path.join(os.getcwd(), "spam")
208 expected_output = f"sys.executable: {expected_path}\n"
209 self.assertIn(expected_output, out)
210 self.assertEqual(err, '')
211
212 def test_pre_initialization_sys_options(self):
213 """
214 Checks that sys.warnoptions and sys._xoptions can be set before the
215 runtime is initialized (otherwise they won't be effective).
216 """
Miss Islington (bot)dd3ede72018-04-27 05:41:25 -0700217 env = dict(os.environ, PYTHONPATH=os.pathsep.join(sys.path))
Miss Islington (bot)c6d94c32018-03-25 04:27:57 -0700218 out, err = self.run_embedded_interpreter(
219 "pre_initialization_sys_options", env=env)
220 expected_output = (
221 "sys.warnoptions: ['once', 'module', 'default']\n"
222 "sys._xoptions: {'not_an_option': '1', 'also_not_an_option': '2'}\n"
223 "warnings.filters[:3]: ['default', 'module', 'once']\n"
224 )
225 self.assertIn(expected_output, out)
Nick Coghlan39f0bb52017-11-28 08:11:51 +1000226 self.assertEqual(err, '')
227
Victor Stinnerb4d1e1f2017-11-30 22:05:00 +0100228 def test_bpo20891(self):
229 """
230 bpo-20891: Calling PyGILState_Ensure in a non-Python thread before
231 calling PyEval_InitThreads() must not crash. PyGILState_Ensure() must
232 call PyEval_InitThreads() for us in this case.
233 """
234 out, err = self.run_embedded_interpreter("bpo20891")
235 self.assertEqual(out, '')
236 self.assertEqual(err, '')
237
Miss Islington (bot)3747dd12018-06-22 10:33:48 -0700238 def test_initialize_twice(self):
239 """
240 bpo-33932: Calling Py_Initialize() twice should do nothing (and not
241 crash!).
242 """
243 out, err = self.run_embedded_interpreter("initialize_twice")
244 self.assertEqual(out, '')
245 self.assertEqual(err, '')
246
Miss Islington (bot)03ec4df2018-07-20 17:16:22 -0700247 def test_initialize_pymain(self):
248 """
249 bpo-34008: Calling Py_Main() after Py_Initialize() must not fail.
250 """
251 out, err = self.run_embedded_interpreter("initialize_pymain")
252 self.assertEqual(out.rstrip(), "Py_Main() after Py_Initialize: sys.argv=['-c', 'arg2']")
253 self.assertEqual(err, '')
254
Nick Coghlan39f0bb52017-11-28 08:11:51 +1000255
Victor Stinner0c90d6f2018-08-05 12:31:59 +0200256class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase):
257 maxDiff = 4096
Victor Stinner9ee1d422018-11-14 18:58:01 +0100258 UTF8_MODE_ERRORS = ('surrogatepass' if MS_WINDOWS else 'surrogateescape')
Victor Stinner35c28d52018-11-14 02:01:52 +0100259
Victor Stinner9ee1d422018-11-14 18:58:01 +0100260 # core config
261 UNTESTED_CORE_CONFIG = (
262 # FIXME: untested core configuration variables
263 'dll_path',
264 'executable',
265 'module_search_paths',
266 )
Victor Stinner35c28d52018-11-14 02:01:52 +0100267 DEFAULT_CORE_CONFIG = {
Victor Stinner0c90d6f2018-08-05 12:31:59 +0200268 'install_signal_handlers': 1,
Victor Stinner35c28d52018-11-14 02:01:52 +0100269 'ignore_environment': 0,
Victor Stinner0c90d6f2018-08-05 12:31:59 +0200270 'use_hash_seed': 0,
271 'hash_seed': 0,
Victor Stinner35c28d52018-11-14 02:01:52 +0100272 'allocator': None,
Victor Stinner0c90d6f2018-08-05 12:31:59 +0200273 'dev_mode': 0,
274 'faulthandler': 0,
275 'tracemalloc': 0,
276 'import_time': 0,
277 'show_ref_count': 0,
278 'show_alloc_count': 0,
279 'dump_refs': 0,
280 'malloc_stats': 0,
Victor Stinner0c90d6f2018-08-05 12:31:59 +0200281
Victor Stinner35c28d52018-11-14 02:01:52 +0100282 'utf8_mode': 0,
Victor Stinner95cc3ee2018-09-19 12:01:52 -0700283 'coerce_c_locale': 0,
284 'coerce_c_locale_warn': 0,
285
Victor Stinner0c90d6f2018-08-05 12:31:59 +0200286 'program_name': './_testembed',
Victor Stinner35c28d52018-11-14 02:01:52 +0100287 'argv': [],
288 'program': None,
Victor Stinner0c90d6f2018-08-05 12:31:59 +0200289
Victor Stinner35c28d52018-11-14 02:01:52 +0100290 'xoptions': [],
291 'warnoptions': [],
Victor Stinner0c90d6f2018-08-05 12:31:59 +0200292
Victor Stinner9ee1d422018-11-14 18:58:01 +0100293 'module_search_path_env': None,
294 'home': None,
295 'prefix': sys.prefix,
296 'base_prefix': sys.base_prefix,
297 'exec_prefix': sys.exec_prefix,
298 'base_exec_prefix': sys.base_exec_prefix,
299
Victor Stinner0c90d6f2018-08-05 12:31:59 +0200300 '_disable_importlib': 0,
Victor Stinner0c90d6f2018-08-05 12:31:59 +0200301 }
302
Victor Stinner9ee1d422018-11-14 18:58:01 +0100303 # main config
Victor Stinner9ee1d422018-11-14 18:58:01 +0100304 COPY_MAIN_CONFIG = (
305 # Copy core config to main config for expected values
306 'argv',
307 'base_exec_prefix',
308 'base_prefix',
309 'exec_prefix',
310 'executable',
311 'install_signal_handlers',
312 'prefix',
313 'warnoptions',
Miss Islington (bot)d2be9a52018-11-16 03:34:35 -0800314 # xoptions is created from core_config in check_main_config().
315 # 'module_search_paths' is copied to 'module_search_path'.
Victor Stinner9ee1d422018-11-14 18:58:01 +0100316 )
317
318 # global config
319 UNTESTED_GLOBAL_CONFIG = (
320 # Py_HasFileSystemDefaultEncoding value depends on the LC_CTYPE locale
321 # and the platform. It is complex to test it, and it's value doesn't
322 # really matter.
323 'Py_HasFileSystemDefaultEncoding',
324 )
325 DEFAULT_GLOBAL_CONFIG = {
326 'Py_BytesWarningFlag': 0,
327 'Py_DebugFlag': 0,
328 'Py_DontWriteBytecodeFlag': 0,
329 # None means that the value is get by get_filesystem_encoding()
330 'Py_FileSystemDefaultEncodeErrors': None,
331 'Py_FileSystemDefaultEncoding': None,
332 'Py_FrozenFlag': 0,
333 'Py_HashRandomizationFlag': 1,
334 'Py_InspectFlag': 0,
335 'Py_InteractiveFlag': 0,
336 'Py_IsolatedFlag': 0,
337 'Py_NoSiteFlag': 0,
338 'Py_NoUserSiteDirectory': 0,
339 'Py_OptimizeFlag': 0,
340 'Py_QuietFlag': 0,
341 'Py_UnbufferedStdioFlag': 0,
342 'Py_VerboseFlag': 0,
343 }
344 if MS_WINDOWS:
345 DEFAULT_GLOBAL_CONFIG.update({
346 'Py_LegacyWindowsFSEncodingFlag': 0,
347 'Py_LegacyWindowsStdioFlag': 0,
348 })
349 COPY_GLOBAL_CONFIG = [
350 # Copy core config to global config for expected values
351 # True means that the core config value is inverted (0 => 1 and 1 => 0)
352 ('Py_IgnoreEnvironmentFlag', 'ignore_environment'),
353 ('Py_UTF8Mode', 'utf8_mode'),
354 ]
355
Victor Stinner35c28d52018-11-14 02:01:52 +0100356 def get_filesystem_encoding(self, isolated, env):
357 code = ('import codecs, locale, sys; '
358 'print(sys.getfilesystemencoding(), '
359 'sys.getfilesystemencodeerrors())')
360 args = (sys.executable, '-c', code)
361 env = dict(env)
362 if not isolated:
363 env['PYTHONCOERCECLOCALE'] = '0'
364 env['PYTHONUTF8'] = '0'
365 proc = subprocess.run(args, text=True, env=env,
366 stdout=subprocess.PIPE,
367 stderr=subprocess.PIPE)
368 if proc.returncode:
369 raise Exception(f"failed to get the locale encoding: "
370 f"stdout={proc.stdout!r} stderr={proc.stderr!r}")
371 out = proc.stdout.rstrip()
372 return out.split()
373
Victor Stinner9ee1d422018-11-14 18:58:01 +0100374 def main_xoptions(self, xoptions_list):
375 xoptions = {}
376 for opt in xoptions_list:
377 if '=' in opt:
378 key, value = opt.split('=', 1)
379 xoptions[key] = value
380 else:
381 xoptions[opt] = True
382 return xoptions
Victor Stinner35c28d52018-11-14 02:01:52 +0100383
Victor Stinner9ee1d422018-11-14 18:58:01 +0100384 def check_main_config(self, config):
385 core_config = config['core_config']
386 main_config = config['main_config']
387
388 # main config
Victor Stinner9ee1d422018-11-14 18:58:01 +0100389 expected_main = {}
390 for key in self.COPY_MAIN_CONFIG:
391 expected_main[key] = core_config[key]
Miss Islington (bot)d2be9a52018-11-16 03:34:35 -0800392 expected_main['module_search_path'] = core_config['module_search_paths']
Victor Stinner9ee1d422018-11-14 18:58:01 +0100393 expected_main['xoptions'] = self.main_xoptions(core_config['xoptions'])
394 self.assertEqual(main_config, expected_main)
395
396 def check_core_config(self, config, expected):
397 expected = dict(self.DEFAULT_CORE_CONFIG, **expected)
398 core_config = dict(config['core_config'])
399 for key in self.UNTESTED_CORE_CONFIG:
400 core_config.pop(key, None)
401 self.assertEqual(core_config, expected)
402
403 def check_global_config(self, config, expected, env):
404 expected = dict(self.DEFAULT_GLOBAL_CONFIG, **expected)
405
406 if expected['Py_FileSystemDefaultEncoding'] is None or expected['Py_FileSystemDefaultEncodeErrors'] is None:
407 res = self.get_filesystem_encoding(expected['Py_IsolatedFlag'], env)
408 if expected['Py_FileSystemDefaultEncoding'] is None:
409 expected['Py_FileSystemDefaultEncoding'] = res[0]
410 if expected['Py_FileSystemDefaultEncodeErrors'] is None:
411 expected['Py_FileSystemDefaultEncodeErrors'] = res[1]
412
413 core_config = config['core_config']
414
415 for item in self.COPY_GLOBAL_CONFIG:
416 if len(item) == 3:
417 global_key, core_key, opposite = item
418 expected[global_key] = 0 if core_config[core_key] else 1
419 else:
420 global_key, core_key = item
421 expected[global_key] = core_config[core_key]
422
423 global_config = dict(config['global_config'])
424 for key in self.UNTESTED_GLOBAL_CONFIG:
425 del global_config[key]
426 self.assertEqual(global_config, expected)
427
428 def check_config(self, testname, expected_core, expected_global):
Victor Stinner0c90d6f2018-08-05 12:31:59 +0200429 env = dict(os.environ)
Victor Stinner9ee1d422018-11-14 18:58:01 +0100430 # Remove PYTHON* environment variables to get deterministic environment
Victor Stinner0c90d6f2018-08-05 12:31:59 +0200431 for key in list(env):
432 if key.startswith('PYTHON'):
433 del env[key]
434 # Disable C locale coercion and UTF-8 mode to not depend
435 # on the current locale
436 env['PYTHONCOERCECLOCALE'] = '0'
437 env['PYTHONUTF8'] = '0'
Victor Stinner35c28d52018-11-14 02:01:52 +0100438
Victor Stinner0c90d6f2018-08-05 12:31:59 +0200439 out, err = self.run_embedded_interpreter(testname, env=env)
440 # Ignore err
Victor Stinner35c28d52018-11-14 02:01:52 +0100441 config = json.loads(out)
Victor Stinner0c90d6f2018-08-05 12:31:59 +0200442
Victor Stinner9ee1d422018-11-14 18:58:01 +0100443 self.check_core_config(config, expected_core)
444 self.check_main_config(config)
445 self.check_global_config(config, expected_global, env)
Victor Stinner0c90d6f2018-08-05 12:31:59 +0200446
447 def test_init_default_config(self):
Victor Stinner35c28d52018-11-14 02:01:52 +0100448 self.check_config("init_default_config", {}, {})
Victor Stinner0c90d6f2018-08-05 12:31:59 +0200449
450 def test_init_global_config(self):
Victor Stinner35c28d52018-11-14 02:01:52 +0100451 core_config = {
Victor Stinner0c90d6f2018-08-05 12:31:59 +0200452 'program_name': './globalvar',
Victor Stinner35c28d52018-11-14 02:01:52 +0100453 'utf8_mode': 1,
454 }
455 global_config = {
Victor Stinner0c90d6f2018-08-05 12:31:59 +0200456 'Py_BytesWarningFlag': 1,
Victor Stinner35c28d52018-11-14 02:01:52 +0100457 'Py_DontWriteBytecodeFlag': 1,
Victor Stinner35c28d52018-11-14 02:01:52 +0100458 'Py_FileSystemDefaultEncodeErrors': self.UTF8_MODE_ERRORS,
459 'Py_FileSystemDefaultEncoding': 'utf-8',
Victor Stinner0c90d6f2018-08-05 12:31:59 +0200460 'Py_InspectFlag': 1,
461 'Py_InteractiveFlag': 1,
Victor Stinner35c28d52018-11-14 02:01:52 +0100462 'Py_NoSiteFlag': 1,
Victor Stinner0c90d6f2018-08-05 12:31:59 +0200463 'Py_NoUserSiteDirectory': 1,
Victor Stinner35c28d52018-11-14 02:01:52 +0100464 'Py_OptimizeFlag': 2,
465 'Py_QuietFlag': 1,
466 'Py_VerboseFlag': 1,
Victor Stinner0c90d6f2018-08-05 12:31:59 +0200467 'Py_FrozenFlag': 1,
Victor Stinner35c28d52018-11-14 02:01:52 +0100468 'Py_UnbufferedStdioFlag': 1,
Victor Stinner0c90d6f2018-08-05 12:31:59 +0200469 }
Victor Stinner35c28d52018-11-14 02:01:52 +0100470 self.check_config("init_global_config", core_config, global_config)
Victor Stinner0c90d6f2018-08-05 12:31:59 +0200471
472 def test_init_from_config(self):
Victor Stinner35c28d52018-11-14 02:01:52 +0100473 core_config = {
Victor Stinner0c90d6f2018-08-05 12:31:59 +0200474 'install_signal_handlers': 0,
475 'use_hash_seed': 1,
476 'hash_seed': 123,
477 'allocator': 'malloc_debug',
478 'tracemalloc': 2,
479 'import_time': 1,
480 'show_ref_count': 1,
481 'show_alloc_count': 1,
482 'malloc_stats': 1,
483
484 'utf8_mode': 1,
485
486 'program_name': './conf_program_name',
Victor Stinner9ee1d422018-11-14 18:58:01 +0100487 'argv': ['-c', 'pass'],
Victor Stinner0c90d6f2018-08-05 12:31:59 +0200488 'program': 'conf_program',
Victor Stinner9ee1d422018-11-14 18:58:01 +0100489 'xoptions': ['core_xoption1=3', 'core_xoption2=', 'core_xoption3'],
490 'warnoptions': ['default', 'error::ResourceWarning'],
Victor Stinner0c90d6f2018-08-05 12:31:59 +0200491
492 'faulthandler': 1,
493 }
Victor Stinner35c28d52018-11-14 02:01:52 +0100494 global_config = {
Victor Stinner35c28d52018-11-14 02:01:52 +0100495 'Py_NoUserSiteDirectory': 0,
496 }
497 self.check_config("init_from_config", core_config, global_config)
Victor Stinner0c90d6f2018-08-05 12:31:59 +0200498
499 def test_init_env(self):
Victor Stinner35c28d52018-11-14 02:01:52 +0100500 core_config = {
Victor Stinner0c90d6f2018-08-05 12:31:59 +0200501 'use_hash_seed': 1,
502 'hash_seed': 42,
503 'allocator': 'malloc_debug',
504 'tracemalloc': 2,
505 'import_time': 1,
506 'malloc_stats': 1,
507 'utf8_mode': 1,
Victor Stinner0c90d6f2018-08-05 12:31:59 +0200508 'faulthandler': 1,
509 'dev_mode': 1,
510 }
Victor Stinner35c28d52018-11-14 02:01:52 +0100511 global_config = {
512 'Py_DontWriteBytecodeFlag': 1,
Victor Stinner35c28d52018-11-14 02:01:52 +0100513 'Py_InspectFlag': 1,
514 'Py_NoUserSiteDirectory': 1,
515 'Py_OptimizeFlag': 2,
516 'Py_UnbufferedStdioFlag': 1,
517 'Py_VerboseFlag': 1,
518 'Py_FileSystemDefaultEncoding': 'utf-8',
519 'Py_FileSystemDefaultEncodeErrors': self.UTF8_MODE_ERRORS,
520 }
521 self.check_config("init_env", core_config, global_config)
Victor Stinner0c90d6f2018-08-05 12:31:59 +0200522
523 def test_init_dev_mode(self):
Victor Stinner35c28d52018-11-14 02:01:52 +0100524 core_config = {
Victor Stinner0c90d6f2018-08-05 12:31:59 +0200525 'dev_mode': 1,
526 'faulthandler': 1,
527 'allocator': 'debug',
528 }
Victor Stinner35c28d52018-11-14 02:01:52 +0100529 self.check_config("init_dev_mode", core_config, {})
Victor Stinner0c90d6f2018-08-05 12:31:59 +0200530
531 def test_init_isolated(self):
Victor Stinner35c28d52018-11-14 02:01:52 +0100532 core_config = {
533 'ignore_environment': 1,
534 }
535 global_config = {
Victor Stinner0c90d6f2018-08-05 12:31:59 +0200536 'Py_IsolatedFlag': 1,
Victor Stinner0c90d6f2018-08-05 12:31:59 +0200537 'Py_NoUserSiteDirectory': 1,
538 }
Victor Stinner35c28d52018-11-14 02:01:52 +0100539 self.check_config("init_isolated", core_config, global_config)
Victor Stinner0c90d6f2018-08-05 12:31:59 +0200540
541
Nick Coghlan39f0bb52017-11-28 08:11:51 +1000542if __name__ == "__main__":
543 unittest.main()