blob: 900a4b1d427a6b8ab54601063129b4e9046a52e6 [file] [log] [blame]
Victor Stinner91c99872019-05-14 22:01:51 +02001#ifndef Py_BUILD_CORE_MODULE
2# define Py_BUILD_CORE_MODULE
3#endif
4
Victor Stinner013a18a2019-06-06 14:25:18 +02005/* Always enable assertion (even in release mode) */
6#undef NDEBUG
7
Antoine Pitrou8e605772011-04-25 21:21:07 +02008#include <Python.h>
Victor Stinner013a18a2019-06-06 14:25:18 +02009#include "pycore_initconfig.h" /* _PyConfig_InitCompatConfig() */
10#include "pycore_pystate.h" /* _PyRuntime */
Victor Stinnerbab0db62019-05-18 03:21:27 +020011#include <Python.h>
Victor Stinnerb4d1e1f2017-11-30 22:05:00 +010012#include "pythread.h"
Eric Snowe3774162017-05-22 19:46:40 -070013#include <inttypes.h>
Antoine Pitrou8e605772011-04-25 21:21:07 +020014#include <stdio.h>
Nick Coghlanbc77eff2018-03-25 20:44:30 +100015#include <wchar.h>
Antoine Pitrou8e605772011-04-25 21:21:07 +020016
Nick Coghlan7d270ee2013-10-17 22:35:35 +100017/*********************************************************
18 * Embedded interpreter tests that need a custom exe
19 *
20 * Executed via 'EmbeddingTests' in Lib/test/test_capi.py
21 *********************************************************/
22
Victor Stinnerbb6bf7d2019-09-24 18:21:02 +020023/* Use path starting with "./" avoids a search along the PATH */
24#define PROGRAM_NAME L"./_testembed"
25
Nick Coghlan7d270ee2013-10-17 22:35:35 +100026static void _testembed_Py_Initialize(void)
27{
Victor Stinnerbb6bf7d2019-09-24 18:21:02 +020028 Py_SetProgramName(PROGRAM_NAME);
Nick Coghlan7d270ee2013-10-17 22:35:35 +100029 Py_Initialize();
30}
31
32
33/*****************************************************
Martin Panter8f265652016-04-19 04:03:41 +000034 * Test repeated initialisation and subinterpreters
Nick Coghlan7d270ee2013-10-17 22:35:35 +100035 *****************************************************/
36
37static void print_subinterp(void)
Antoine Pitrou8e605772011-04-25 21:21:07 +020038{
Eric Snowe3774162017-05-22 19:46:40 -070039 /* Output information about the interpreter in the format
40 expected in Lib/test/test_capi.py (test_subinterps). */
Antoine Pitrou8e605772011-04-25 21:21:07 +020041 PyThreadState *ts = PyThreadState_Get();
Eric Snowe3774162017-05-22 19:46:40 -070042 PyInterpreterState *interp = ts->interp;
43 int64_t id = PyInterpreterState_GetID(interp);
Eric Snowd1c3c132017-05-24 17:19:47 -070044 printf("interp %" PRId64 " <0x%" PRIXPTR ">, thread state <0x%" PRIXPTR ">: ",
Eric Snowe3774162017-05-22 19:46:40 -070045 id, (uintptr_t)interp, (uintptr_t)ts);
Antoine Pitrou8e605772011-04-25 21:21:07 +020046 fflush(stdout);
47 PyRun_SimpleString(
48 "import sys;"
49 "print('id(modules) =', id(sys.modules));"
50 "sys.stdout.flush()"
51 );
52}
53
Steve Dowerea74f0c2017-01-01 20:25:03 -080054static int test_repeated_init_and_subinterpreters(void)
Antoine Pitrou8e605772011-04-25 21:21:07 +020055{
56 PyThreadState *mainstate, *substate;
57 PyGILState_STATE gilstate;
58 int i, j;
59
Ned Deily939231b2016-08-16 00:17:42 -040060 for (i=0; i<15; i++) {
Antoine Pitrou8e605772011-04-25 21:21:07 +020061 printf("--- Pass %d ---\n", i);
Nick Coghlan7d270ee2013-10-17 22:35:35 +100062 _testembed_Py_Initialize();
Antoine Pitrou8e605772011-04-25 21:21:07 +020063 mainstate = PyThreadState_Get();
64
Antoine Pitrou8e605772011-04-25 21:21:07 +020065 PyEval_ReleaseThread(mainstate);
66
67 gilstate = PyGILState_Ensure();
68 print_subinterp();
69 PyThreadState_Swap(NULL);
70
71 for (j=0; j<3; j++) {
72 substate = Py_NewInterpreter();
73 print_subinterp();
74 Py_EndInterpreter(substate);
75 }
76
77 PyThreadState_Swap(mainstate);
78 print_subinterp();
79 PyGILState_Release(gilstate);
Antoine Pitrou8e605772011-04-25 21:21:07 +020080
81 PyEval_RestoreThread(mainstate);
82 Py_Finalize();
83 }
Steve Dowerea74f0c2017-01-01 20:25:03 -080084 return 0;
Nick Coghlan7d270ee2013-10-17 22:35:35 +100085}
86
87/*****************************************************
88 * Test forcing a particular IO encoding
89 *****************************************************/
90
91static void check_stdio_details(const char *encoding, const char * errors)
92{
93 /* Output info for the test case to check */
94 if (encoding) {
95 printf("Expected encoding: %s\n", encoding);
96 } else {
97 printf("Expected encoding: default\n");
98 }
99 if (errors) {
100 printf("Expected errors: %s\n", errors);
101 } else {
102 printf("Expected errors: default\n");
103 }
104 fflush(stdout);
105 /* Force the given IO encoding */
106 Py_SetStandardStreamEncoding(encoding, errors);
107 _testembed_Py_Initialize();
108 PyRun_SimpleString(
109 "import sys;"
110 "print('stdin: {0.encoding}:{0.errors}'.format(sys.stdin));"
111 "print('stdout: {0.encoding}:{0.errors}'.format(sys.stdout));"
112 "print('stderr: {0.encoding}:{0.errors}'.format(sys.stderr));"
113 "sys.stdout.flush()"
114 );
115 Py_Finalize();
116}
117
Steve Dowerea74f0c2017-01-01 20:25:03 -0800118static int test_forced_io_encoding(void)
Nick Coghlan7d270ee2013-10-17 22:35:35 +1000119{
120 /* Check various combinations */
121 printf("--- Use defaults ---\n");
122 check_stdio_details(NULL, NULL);
123 printf("--- Set errors only ---\n");
Victor Stinnerb2bef622014-03-18 02:38:12 +0100124 check_stdio_details(NULL, "ignore");
Nick Coghlan7d270ee2013-10-17 22:35:35 +1000125 printf("--- Set encoding only ---\n");
Victor Stinner9e4994d2018-08-28 23:26:33 +0200126 check_stdio_details("iso8859-1", NULL);
Nick Coghlan7d270ee2013-10-17 22:35:35 +1000127 printf("--- Set encoding and errors ---\n");
Victor Stinner9e4994d2018-08-28 23:26:33 +0200128 check_stdio_details("iso8859-1", "replace");
Nick Coghlan7d270ee2013-10-17 22:35:35 +1000129
130 /* Check calling after initialization fails */
131 Py_Initialize();
132
133 if (Py_SetStandardStreamEncoding(NULL, NULL) == 0) {
134 printf("Unexpected success calling Py_SetStandardStreamEncoding");
135 }
136 Py_Finalize();
Steve Dowerea74f0c2017-01-01 20:25:03 -0800137 return 0;
Nick Coghlan7d270ee2013-10-17 22:35:35 +1000138}
139
Victor Stinner9e87e772017-11-24 12:09:24 +0100140/*********************************************************
141 * Test parts of the C-API that work before initialization
142 *********************************************************/
143
Nick Coghlanbc77eff2018-03-25 20:44:30 +1000144/* The pre-initialization tests tend to break by segfaulting, so explicitly
145 * flushed progress messages make the broken API easier to find when they fail.
146 */
147#define _Py_EMBED_PREINIT_CHECK(msg) \
148 do {printf(msg); fflush(stdout);} while (0);
149
Victor Stinner9e87e772017-11-24 12:09:24 +0100150static int test_pre_initialization_api(void)
151{
Victor Stinnera9df6512019-03-05 23:31:54 +0100152 /* the test doesn't support custom memory allocators */
153 putenv("PYTHONMALLOC=");
154
Nick Coghlan42746092017-11-26 14:19:13 +1000155 /* Leading "./" ensures getpath.c can still find the standard library */
Nick Coghlanbc77eff2018-03-25 20:44:30 +1000156 _Py_EMBED_PREINIT_CHECK("Checking Py_DecodeLocale\n");
Nick Coghlan42746092017-11-26 14:19:13 +1000157 wchar_t *program = Py_DecodeLocale("./spam", NULL);
Victor Stinner9e87e772017-11-24 12:09:24 +0100158 if (program == NULL) {
159 fprintf(stderr, "Fatal error: cannot decode program name\n");
160 return 1;
161 }
Nick Coghlanbc77eff2018-03-25 20:44:30 +1000162 _Py_EMBED_PREINIT_CHECK("Checking Py_SetProgramName\n");
Victor Stinner9e87e772017-11-24 12:09:24 +0100163 Py_SetProgramName(program);
164
Nick Coghlanbc77eff2018-03-25 20:44:30 +1000165 _Py_EMBED_PREINIT_CHECK("Initializing interpreter\n");
Victor Stinner9e87e772017-11-24 12:09:24 +0100166 Py_Initialize();
Nick Coghlanbc77eff2018-03-25 20:44:30 +1000167 _Py_EMBED_PREINIT_CHECK("Check sys module contents\n");
168 PyRun_SimpleString("import sys; "
169 "print('sys.executable:', sys.executable)");
170 _Py_EMBED_PREINIT_CHECK("Finalizing interpreter\n");
Victor Stinner9e87e772017-11-24 12:09:24 +0100171 Py_Finalize();
172
Nick Coghlanbc77eff2018-03-25 20:44:30 +1000173 _Py_EMBED_PREINIT_CHECK("Freeing memory allocated by Py_DecodeLocale\n");
Victor Stinner9e87e772017-11-24 12:09:24 +0100174 PyMem_RawFree(program);
175 return 0;
176}
177
Nick Coghlanbc77eff2018-03-25 20:44:30 +1000178
179/* bpo-33042: Ensure embedding apps can predefine sys module options */
180static int test_pre_initialization_sys_options(void)
181{
Nick Coghlan69f5c732018-03-30 15:36:42 +1000182 /* We allocate a couple of the options dynamically, and then delete
Nick Coghlanbc77eff2018-03-25 20:44:30 +1000183 * them before calling Py_Initialize. This ensures the interpreter isn't
184 * relying on the caller to keep the passed in strings alive.
185 */
Nick Coghlan69f5c732018-03-30 15:36:42 +1000186 const wchar_t *static_warnoption = L"once";
187 const wchar_t *static_xoption = L"also_not_an_option=2";
Nick Coghlanbc77eff2018-03-25 20:44:30 +1000188 size_t warnoption_len = wcslen(static_warnoption);
189 size_t xoption_len = wcslen(static_xoption);
Nick Coghlan69f5c732018-03-30 15:36:42 +1000190 wchar_t *dynamic_once_warnoption = \
191 (wchar_t *) calloc(warnoption_len+1, sizeof(wchar_t));
192 wchar_t *dynamic_xoption = \
193 (wchar_t *) calloc(xoption_len+1, sizeof(wchar_t));
Nick Coghlanbc77eff2018-03-25 20:44:30 +1000194 wcsncpy(dynamic_once_warnoption, static_warnoption, warnoption_len+1);
195 wcsncpy(dynamic_xoption, static_xoption, xoption_len+1);
196
197 _Py_EMBED_PREINIT_CHECK("Checking PySys_AddWarnOption\n");
198 PySys_AddWarnOption(L"default");
199 _Py_EMBED_PREINIT_CHECK("Checking PySys_ResetWarnOptions\n");
200 PySys_ResetWarnOptions();
201 _Py_EMBED_PREINIT_CHECK("Checking PySys_AddWarnOption linked list\n");
202 PySys_AddWarnOption(dynamic_once_warnoption);
203 PySys_AddWarnOption(L"module");
204 PySys_AddWarnOption(L"default");
205 _Py_EMBED_PREINIT_CHECK("Checking PySys_AddXOption\n");
206 PySys_AddXOption(L"not_an_option=1");
207 PySys_AddXOption(dynamic_xoption);
208
209 /* Delete the dynamic options early */
210 free(dynamic_once_warnoption);
211 dynamic_once_warnoption = NULL;
212 free(dynamic_xoption);
213 dynamic_xoption = NULL;
214
215 _Py_EMBED_PREINIT_CHECK("Initializing interpreter\n");
216 _testembed_Py_Initialize();
217 _Py_EMBED_PREINIT_CHECK("Check sys module contents\n");
218 PyRun_SimpleString("import sys; "
219 "print('sys.warnoptions:', sys.warnoptions); "
220 "print('sys._xoptions:', sys._xoptions); "
221 "warnings = sys.modules['warnings']; "
222 "latest_filters = [f[0] for f in warnings.filters[:3]]; "
223 "print('warnings.filters[:3]:', latest_filters)");
224 _Py_EMBED_PREINIT_CHECK("Finalizing interpreter\n");
225 Py_Finalize();
226
227 return 0;
228}
229
230
231/* bpo-20891: Avoid race condition when initialising the GIL */
Victor Stinnerb4d1e1f2017-11-30 22:05:00 +0100232static void bpo20891_thread(void *lockp)
233{
234 PyThread_type_lock lock = *((PyThread_type_lock*)lockp);
235
236 PyGILState_STATE state = PyGILState_Ensure();
237 if (!PyGILState_Check()) {
238 fprintf(stderr, "PyGILState_Check failed!");
239 abort();
240 }
241
242 PyGILState_Release(state);
243
244 PyThread_release_lock(lock);
245
246 PyThread_exit_thread();
247}
248
249static int test_bpo20891(void)
250{
Victor Stinnera9df6512019-03-05 23:31:54 +0100251 /* the test doesn't support custom memory allocators */
252 putenv("PYTHONMALLOC=");
253
Victor Stinner3225b9f2020-03-09 20:56:57 +0100254 /* bpo-20891: Calling PyGILState_Ensure in a non-Python thread must not
255 crash. */
Victor Stinnerb4d1e1f2017-11-30 22:05:00 +0100256 PyThread_type_lock lock = PyThread_allocate_lock();
257 if (!lock) {
258 fprintf(stderr, "PyThread_allocate_lock failed!");
259 return 1;
260 }
261
262 _testembed_Py_Initialize();
263
264 unsigned long thrd = PyThread_start_new_thread(bpo20891_thread, &lock);
265 if (thrd == PYTHREAD_INVALID_THREAD_ID) {
266 fprintf(stderr, "PyThread_start_new_thread failed!");
267 return 1;
268 }
269 PyThread_acquire_lock(lock, WAIT_LOCK);
270
271 Py_BEGIN_ALLOW_THREADS
272 /* wait until the thread exit */
273 PyThread_acquire_lock(lock, WAIT_LOCK);
274 Py_END_ALLOW_THREADS
275
276 PyThread_free_lock(lock);
277
278 return 0;
279}
280
Victor Stinner209abf72018-06-22 19:14:51 +0200281static int test_initialize_twice(void)
282{
283 _testembed_Py_Initialize();
284
285 /* bpo-33932: Calling Py_Initialize() twice should do nothing
286 * (and not crash!). */
287 Py_Initialize();
288
289 Py_Finalize();
290
291 return 0;
292}
293
Victor Stinnerfb47bca2018-07-20 17:34:23 +0200294static int test_initialize_pymain(void)
295{
296 wchar_t *argv[] = {L"PYTHON", L"-c",
Victor Stinnercab5d072019-05-17 19:01:14 +0200297 (L"import sys; "
298 L"print(f'Py_Main() after Py_Initialize: "
299 L"sys.argv={sys.argv}')"),
Victor Stinnerfb47bca2018-07-20 17:34:23 +0200300 L"arg2"};
301 _testembed_Py_Initialize();
302
303 /* bpo-34008: Calling Py_Main() after Py_Initialize() must not crash */
304 Py_Main(Py_ARRAY_LENGTH(argv), argv);
305
306 Py_Finalize();
307
308 return 0;
309}
310
Victor Stinner9e87e772017-11-24 12:09:24 +0100311
Victor Stinner00b137c2018-11-13 19:59:26 +0100312static void
313dump_config(void)
314{
Victor Stinner23bace22019-04-18 11:37:26 +0200315 (void) PyRun_SimpleStringFlags(
316 "import _testinternalcapi, json; "
317 "print(json.dumps(_testinternalcapi.get_configs()))",
318 0);
Victor Stinner00b137c2018-11-13 19:59:26 +0100319}
320
321
Victor Stinner022be022019-05-22 23:58:50 +0200322static int test_init_initialize_config(void)
Victor Stinner56b29b62018-07-26 18:57:56 +0200323{
324 _testembed_Py_Initialize();
325 dump_config();
326 Py_Finalize();
327 return 0;
328}
329
330
Victor Stinner67310022019-07-01 19:52:45 +0200331static void config_set_string(PyConfig *config, wchar_t **config_str, const wchar_t *str)
332{
333 PyStatus status = PyConfig_SetString(config, config_str, str);
334 if (PyStatus_Exception(status)) {
335 PyConfig_Clear(config);
336 Py_ExitStatusException(status);
337 }
338}
339
340
341static void config_set_argv(PyConfig *config, Py_ssize_t argc, wchar_t * const *argv)
342{
343 PyStatus status = PyConfig_SetArgv(config, argc, argv);
344 if (PyStatus_Exception(status)) {
345 PyConfig_Clear(config);
346 Py_ExitStatusException(status);
347 }
348}
349
350
351static void
352config_set_wide_string_list(PyConfig *config, PyWideStringList *list,
353 Py_ssize_t length, wchar_t **items)
354{
355 PyStatus status = PyConfig_SetWideStringList(config, list, length, items);
356 if (PyStatus_Exception(status)) {
357 PyConfig_Clear(config);
358 Py_ExitStatusException(status);
359 }
360}
361
362
363static void config_set_program_name(PyConfig *config)
364{
Victor Stinnerbb6bf7d2019-09-24 18:21:02 +0200365 const wchar_t *program_name = PROGRAM_NAME;
Victor Stinner67310022019-07-01 19:52:45 +0200366 config_set_string(config, &config->program_name, program_name);
367}
368
369
370static void init_from_config_clear(PyConfig *config)
371{
372 PyStatus status = Py_InitializeFromConfig(config);
373 PyConfig_Clear(config);
374 if (PyStatus_Exception(status)) {
375 Py_ExitStatusException(status);
376 }
377}
378
379
Victor Stinner022be022019-05-22 23:58:50 +0200380static int check_init_compat_config(int preinit)
381{
Victor Stinner331a6a52019-05-27 16:39:22 +0200382 PyStatus status;
Victor Stinner022be022019-05-22 23:58:50 +0200383
384 if (preinit) {
Victor Stinner331a6a52019-05-27 16:39:22 +0200385 PyPreConfig preconfig;
Victor Stinner3c30a762019-10-01 10:56:37 +0200386 _PyPreConfig_InitCompatConfig(&preconfig);
Victor Stinner022be022019-05-22 23:58:50 +0200387
Victor Stinner331a6a52019-05-27 16:39:22 +0200388 status = Py_PreInitialize(&preconfig);
389 if (PyStatus_Exception(status)) {
390 Py_ExitStatusException(status);
Victor Stinner022be022019-05-22 23:58:50 +0200391 }
392 }
393
Victor Stinner331a6a52019-05-27 16:39:22 +0200394 PyConfig config;
Victor Stinner8462a492019-10-01 12:06:16 +0200395 _PyConfig_InitCompatConfig(&config);
Victor Stinner441b10c2019-09-28 04:28:35 +0200396
Victor Stinner67310022019-07-01 19:52:45 +0200397 config_set_program_name(&config);
398 init_from_config_clear(&config);
Victor Stinner022be022019-05-22 23:58:50 +0200399
400 dump_config();
401 Py_Finalize();
402 return 0;
403}
404
405
406static int test_preinit_compat_config(void)
407{
408 return check_init_compat_config(1);
409}
410
411
412static int test_init_compat_config(void)
413{
414 return check_init_compat_config(0);
415}
416
417
Victor Stinner56b29b62018-07-26 18:57:56 +0200418static int test_init_global_config(void)
419{
420 /* FIXME: test Py_IgnoreEnvironmentFlag */
421
422 putenv("PYTHONUTF8=0");
423 Py_UTF8Mode = 1;
424
425 /* Test initialization from global configuration variables (Py_xxx) */
426 Py_SetProgramName(L"./globalvar");
427
428 /* Py_IsolatedFlag is not tested */
429 Py_NoSiteFlag = 1;
430 Py_BytesWarningFlag = 1;
431
432 putenv("PYTHONINSPECT=");
433 Py_InspectFlag = 1;
434
435 putenv("PYTHONOPTIMIZE=0");
436 Py_InteractiveFlag = 1;
437
438 putenv("PYTHONDEBUG=0");
439 Py_OptimizeFlag = 2;
440
441 /* Py_DebugFlag is not tested */
442
443 putenv("PYTHONDONTWRITEBYTECODE=");
444 Py_DontWriteBytecodeFlag = 1;
445
446 putenv("PYTHONVERBOSE=0");
447 Py_VerboseFlag = 1;
448
449 Py_QuietFlag = 1;
450 Py_NoUserSiteDirectory = 1;
451
452 putenv("PYTHONUNBUFFERED=");
453 Py_UnbufferedStdioFlag = 1;
454
Victor Stinner54b43bb2019-05-16 18:30:15 +0200455 Py_FrozenFlag = 1;
456
Victor Stinner56b29b62018-07-26 18:57:56 +0200457 /* FIXME: test Py_LegacyWindowsFSEncodingFlag */
458 /* FIXME: test Py_LegacyWindowsStdioFlag */
459
Victor Stinner56b29b62018-07-26 18:57:56 +0200460 Py_Initialize();
461 dump_config();
462 Py_Finalize();
463 return 0;
464}
465
466
467static int test_init_from_config(void)
468{
Victor Stinner331a6a52019-05-27 16:39:22 +0200469 PyPreConfig preconfig;
Victor Stinner3c30a762019-10-01 10:56:37 +0200470 _PyPreConfig_InitCompatConfig(&preconfig);
Victor Stinner20004952019-03-26 02:31:11 +0100471
472 putenv("PYTHONMALLOC=malloc_debug");
Victor Stinnerb16b4e42019-05-17 15:20:52 +0200473 preconfig.allocator = PYMEM_ALLOCATOR_MALLOC;
Victor Stinner20004952019-03-26 02:31:11 +0100474
475 putenv("PYTHONUTF8=0");
476 Py_UTF8Mode = 0;
477 preconfig.utf8_mode = 1;
478
Victor Stinner3c30a762019-10-01 10:56:37 +0200479 PyStatus status = Py_PreInitialize(&preconfig);
Victor Stinner331a6a52019-05-27 16:39:22 +0200480 if (PyStatus_Exception(status)) {
481 Py_ExitStatusException(status);
Victor Stinner20004952019-03-26 02:31:11 +0100482 }
483
Victor Stinner331a6a52019-05-27 16:39:22 +0200484 PyConfig config;
Victor Stinner8462a492019-10-01 12:06:16 +0200485 _PyConfig_InitCompatConfig(&config);
Victor Stinner441b10c2019-09-28 04:28:35 +0200486
Victor Stinner56b29b62018-07-26 18:57:56 +0200487 config.install_signal_handlers = 0;
488
489 /* FIXME: test use_environment */
490
491 putenv("PYTHONHASHSEED=42");
492 config.use_hash_seed = 1;
493 config.hash_seed = 123;
494
Victor Stinnerbab0db62019-05-18 03:21:27 +0200495 /* dev_mode=1 is tested in test_init_dev_mode() */
Victor Stinner56b29b62018-07-26 18:57:56 +0200496
497 putenv("PYTHONFAULTHANDLER=");
498 config.faulthandler = 1;
499
500 putenv("PYTHONTRACEMALLOC=0");
501 config.tracemalloc = 2;
502
503 putenv("PYTHONPROFILEIMPORTTIME=0");
504 config.import_time = 1;
505
506 config.show_ref_count = 1;
Victor Stinner56b29b62018-07-26 18:57:56 +0200507 /* FIXME: test dump_refs: bpo-34223 */
508
509 putenv("PYTHONMALLOCSTATS=0");
510 config.malloc_stats = 1;
511
Victor Stinner56b29b62018-07-26 18:57:56 +0200512 putenv("PYTHONPYCACHEPREFIX=env_pycache_prefix");
Victor Stinner67310022019-07-01 19:52:45 +0200513 config_set_string(&config, &config.pycache_prefix, L"conf_pycache_prefix");
Victor Stinner56b29b62018-07-26 18:57:56 +0200514
515 Py_SetProgramName(L"./globalvar");
Victor Stinner67310022019-07-01 19:52:45 +0200516 config_set_string(&config, &config.program_name, L"./conf_program_name");
Victor Stinner56b29b62018-07-26 18:57:56 +0200517
Victor Stinner67310022019-07-01 19:52:45 +0200518 wchar_t* argv[] = {
Victor Stinner2f549082019-03-29 15:13:46 +0100519 L"python3",
Victor Stinner67310022019-07-01 19:52:45 +0200520 L"-W",
521 L"cmdline_warnoption",
522 L"-X",
523 L"cmdline_xoption",
Victor Stinner01de89c2018-11-14 17:39:45 +0100524 L"-c",
525 L"pass",
Victor Stinner2f549082019-03-29 15:13:46 +0100526 L"arg2",
Victor Stinner01de89c2018-11-14 17:39:45 +0100527 };
Victor Stinner67310022019-07-01 19:52:45 +0200528 config_set_argv(&config, Py_ARRAY_LENGTH(argv), argv);
Victor Stinnercab5d072019-05-17 19:01:14 +0200529 config.parse_argv = 1;
Victor Stinner01de89c2018-11-14 17:39:45 +0100530
Victor Stinner67310022019-07-01 19:52:45 +0200531 wchar_t* xoptions[3] = {
532 L"config_xoption1=3",
533 L"config_xoption2=",
534 L"config_xoption3",
Victor Stinner01de89c2018-11-14 17:39:45 +0100535 };
Victor Stinner67310022019-07-01 19:52:45 +0200536 config_set_wide_string_list(&config, &config.xoptions,
537 Py_ARRAY_LENGTH(xoptions), xoptions);
Victor Stinner01de89c2018-11-14 17:39:45 +0100538
Victor Stinner67310022019-07-01 19:52:45 +0200539 wchar_t* warnoptions[1] = {
540 L"config_warnoption",
Victor Stinner01de89c2018-11-14 17:39:45 +0100541 };
Victor Stinner67310022019-07-01 19:52:45 +0200542 config_set_wide_string_list(&config, &config.warnoptions,
543 Py_ARRAY_LENGTH(warnoptions), warnoptions);
Victor Stinner01de89c2018-11-14 17:39:45 +0100544
Victor Stinner331a6a52019-05-27 16:39:22 +0200545 /* FIXME: test pythonpath_env */
Victor Stinner56b29b62018-07-26 18:57:56 +0200546 /* FIXME: test home */
547 /* FIXME: test path config: module_search_path .. dll_path */
548
549 putenv("PYTHONVERBOSE=0");
550 Py_VerboseFlag = 0;
551 config.verbose = 1;
552
553 Py_NoSiteFlag = 0;
554 config.site_import = 0;
555
556 Py_BytesWarningFlag = 0;
557 config.bytes_warning = 1;
558
559 putenv("PYTHONINSPECT=");
560 Py_InspectFlag = 0;
561 config.inspect = 1;
562
563 Py_InteractiveFlag = 0;
564 config.interactive = 1;
565
566 putenv("PYTHONOPTIMIZE=0");
567 Py_OptimizeFlag = 1;
568 config.optimization_level = 2;
569
Victor Stinner98512272018-08-01 03:07:00 +0200570 /* FIXME: test parser_debug */
Victor Stinner56b29b62018-07-26 18:57:56 +0200571
572 putenv("PYTHONDONTWRITEBYTECODE=");
573 Py_DontWriteBytecodeFlag = 0;
574 config.write_bytecode = 0;
575
576 Py_QuietFlag = 0;
577 config.quiet = 1;
578
Victor Stinnercab5d072019-05-17 19:01:14 +0200579 config.configure_c_stdio = 1;
Victor Stinner54b43bb2019-05-16 18:30:15 +0200580
Victor Stinner56b29b62018-07-26 18:57:56 +0200581 putenv("PYTHONUNBUFFERED=");
582 Py_UnbufferedStdioFlag = 0;
Victor Stinner98512272018-08-01 03:07:00 +0200583 config.buffered_stdio = 0;
Victor Stinner56b29b62018-07-26 18:57:56 +0200584
Victor Stinnerdfe0dc72018-08-29 11:47:29 +0200585 putenv("PYTHONIOENCODING=cp424");
586 Py_SetStandardStreamEncoding("ascii", "ignore");
Victor Stinner01de89c2018-11-14 17:39:45 +0100587#ifdef MS_WINDOWS
588 /* Py_SetStandardStreamEncoding() sets Py_LegacyWindowsStdioFlag to 1.
589 Force it to 0 through the config. */
590 config.legacy_windows_stdio = 0;
591#endif
Victor Stinner67310022019-07-01 19:52:45 +0200592 config_set_string(&config, &config.stdio_encoding, L"iso8859-1");
593 config_set_string(&config, &config.stdio_errors, L"replace");
Victor Stinnerdfe0dc72018-08-29 11:47:29 +0200594
Victor Stinner56b29b62018-07-26 18:57:56 +0200595 putenv("PYTHONNOUSERSITE=");
596 Py_NoUserSiteDirectory = 0;
597 config.user_site_directory = 0;
598
Victor Stinner67310022019-07-01 19:52:45 +0200599 config_set_string(&config, &config.check_hash_pycs_mode, L"always");
Victor Stinner56b29b62018-07-26 18:57:56 +0200600
Victor Stinner54b43bb2019-05-16 18:30:15 +0200601 Py_FrozenFlag = 0;
602 config.pathconfig_warnings = 0;
603
Victor Stinner67310022019-07-01 19:52:45 +0200604 init_from_config_clear(&config);
605
Victor Stinner56b29b62018-07-26 18:57:56 +0200606 dump_config();
607 Py_Finalize();
608 return 0;
609}
610
611
Victor Stinnerbab0db62019-05-18 03:21:27 +0200612static int check_init_parse_argv(int parse_argv)
Victor Stinnerae239f62019-05-16 17:02:56 +0200613{
Victor Stinner331a6a52019-05-27 16:39:22 +0200614 PyConfig config;
Victor Stinner8462a492019-10-01 12:06:16 +0200615 PyConfig_InitPythonConfig(&config);
Victor Stinnerae239f62019-05-16 17:02:56 +0200616
Victor Stinner67310022019-07-01 19:52:45 +0200617 config.parse_argv = parse_argv;
618
619 wchar_t* argv[] = {
Victor Stinnercab5d072019-05-17 19:01:14 +0200620 L"./argv0",
621 L"-E",
Victor Stinnerae239f62019-05-16 17:02:56 +0200622 L"-c",
Victor Stinnercab5d072019-05-17 19:01:14 +0200623 L"pass",
Victor Stinnerae239f62019-05-16 17:02:56 +0200624 L"arg1",
Victor Stinnercab5d072019-05-17 19:01:14 +0200625 L"-v",
626 L"arg3",
Victor Stinnerae239f62019-05-16 17:02:56 +0200627 };
Victor Stinner67310022019-07-01 19:52:45 +0200628 config_set_argv(&config, Py_ARRAY_LENGTH(argv), argv);
629 init_from_config_clear(&config);
Victor Stinnerae239f62019-05-16 17:02:56 +0200630
Victor Stinnerae239f62019-05-16 17:02:56 +0200631 dump_config();
632 Py_Finalize();
633 return 0;
634}
635
636
Victor Stinnerbab0db62019-05-18 03:21:27 +0200637static int test_init_parse_argv(void)
Victor Stinnercab5d072019-05-17 19:01:14 +0200638{
Victor Stinnerbab0db62019-05-18 03:21:27 +0200639 return check_init_parse_argv(1);
Victor Stinnercab5d072019-05-17 19:01:14 +0200640}
641
642
Victor Stinnerbab0db62019-05-18 03:21:27 +0200643static int test_init_dont_parse_argv(void)
Victor Stinnercab5d072019-05-17 19:01:14 +0200644{
Victor Stinnerbab0db62019-05-18 03:21:27 +0200645 return check_init_parse_argv(0);
Victor Stinnercab5d072019-05-17 19:01:14 +0200646}
647
648
Victor Stinner425717f2019-05-20 16:38:48 +0200649static void set_most_env_vars(void)
Victor Stinner56b29b62018-07-26 18:57:56 +0200650{
651 putenv("PYTHONHASHSEED=42");
Victor Stinner25d13f32019-03-06 12:51:53 +0100652 putenv("PYTHONMALLOC=malloc");
Victor Stinner56b29b62018-07-26 18:57:56 +0200653 putenv("PYTHONTRACEMALLOC=2");
654 putenv("PYTHONPROFILEIMPORTTIME=1");
655 putenv("PYTHONMALLOCSTATS=1");
656 putenv("PYTHONUTF8=1");
657 putenv("PYTHONVERBOSE=1");
658 putenv("PYTHONINSPECT=1");
659 putenv("PYTHONOPTIMIZE=2");
660 putenv("PYTHONDONTWRITEBYTECODE=1");
661 putenv("PYTHONUNBUFFERED=1");
662 putenv("PYTHONPYCACHEPREFIX=env_pycache_prefix");
663 putenv("PYTHONNOUSERSITE=1");
664 putenv("PYTHONFAULTHANDLER=1");
Victor Stinnerdfe0dc72018-08-29 11:47:29 +0200665 putenv("PYTHONIOENCODING=iso8859-1:replace");
Victor Stinner425717f2019-05-20 16:38:48 +0200666}
667
668
669static void set_all_env_vars(void)
670{
671 set_most_env_vars();
672
673 putenv("PYTHONWARNINGS=EnvVar");
674 putenv("PYTHONPATH=/my/path");
Victor Stinner56b29b62018-07-26 18:57:56 +0200675}
676
677
Victor Stinner20e1e252019-05-23 04:12:27 +0200678static int test_init_compat_env(void)
Victor Stinner56b29b62018-07-26 18:57:56 +0200679{
680 /* Test initialization from environment variables */
681 Py_IgnoreEnvironmentFlag = 0;
Victor Stinner6d1c4672019-05-20 11:02:00 +0200682 set_all_env_vars();
Victor Stinner56b29b62018-07-26 18:57:56 +0200683 _testembed_Py_Initialize();
684 dump_config();
685 Py_Finalize();
686 return 0;
687}
688
689
Victor Stinner20e1e252019-05-23 04:12:27 +0200690static int test_init_python_env(void)
691{
Victor Stinner20e1e252019-05-23 04:12:27 +0200692 set_all_env_vars();
693
Victor Stinner331a6a52019-05-27 16:39:22 +0200694 PyConfig config;
Victor Stinner8462a492019-10-01 12:06:16 +0200695 PyConfig_InitPythonConfig(&config);
Victor Stinner20e1e252019-05-23 04:12:27 +0200696
Victor Stinner67310022019-07-01 19:52:45 +0200697 config_set_program_name(&config);
698 init_from_config_clear(&config);
699
Victor Stinner20e1e252019-05-23 04:12:27 +0200700 dump_config();
701 Py_Finalize();
702 return 0;
703}
704
705
Victor Stinner6d1c4672019-05-20 11:02:00 +0200706static void set_all_env_vars_dev_mode(void)
Victor Stinner25d13f32019-03-06 12:51:53 +0100707{
Victor Stinner25d13f32019-03-06 12:51:53 +0100708 putenv("PYTHONMALLOC=");
709 putenv("PYTHONFAULTHANDLER=");
710 putenv("PYTHONDEVMODE=1");
711}
712
713
Victor Stinnerb35be4b2019-03-05 17:37:44 +0100714static int test_init_env_dev_mode(void)
715{
716 /* Test initialization from environment variables */
717 Py_IgnoreEnvironmentFlag = 0;
Victor Stinner6d1c4672019-05-20 11:02:00 +0200718 set_all_env_vars_dev_mode();
Victor Stinnerb35be4b2019-03-05 17:37:44 +0100719 _testembed_Py_Initialize();
720 dump_config();
721 Py_Finalize();
722 return 0;
723}
724
725
Victor Stinner25d13f32019-03-06 12:51:53 +0100726static int test_init_env_dev_mode_alloc(void)
727{
728 /* Test initialization from environment variables */
729 Py_IgnoreEnvironmentFlag = 0;
Victor Stinner6d1c4672019-05-20 11:02:00 +0200730 set_all_env_vars_dev_mode();
Victor Stinner25d13f32019-03-06 12:51:53 +0100731 putenv("PYTHONMALLOC=malloc");
732 _testembed_Py_Initialize();
733 dump_config();
734 Py_Finalize();
735 return 0;
736}
737
738
Victor Stinnerbab0db62019-05-18 03:21:27 +0200739static int test_init_isolated_flag(void)
Victor Stinner56b29b62018-07-26 18:57:56 +0200740{
Victor Stinner331a6a52019-05-27 16:39:22 +0200741 /* Test PyConfig.isolated=1 */
742 PyConfig config;
Victor Stinner8462a492019-10-01 12:06:16 +0200743 PyConfig_InitPythonConfig(&config);
Victor Stinner56b29b62018-07-26 18:57:56 +0200744
Victor Stinnercad1f742019-03-05 02:01:27 +0100745 Py_IsolatedFlag = 0;
Victor Stinner20004952019-03-26 02:31:11 +0100746 config.isolated = 1;
Victor Stinnercad1f742019-03-05 02:01:27 +0100747
Victor Stinner67310022019-07-01 19:52:45 +0200748 config_set_program_name(&config);
Victor Stinnerbab0db62019-05-18 03:21:27 +0200749 set_all_env_vars();
Victor Stinner67310022019-07-01 19:52:45 +0200750 init_from_config_clear(&config);
751
Victor Stinner56b29b62018-07-26 18:57:56 +0200752 dump_config();
753 Py_Finalize();
754 return 0;
755}
756
757
Victor Stinner331a6a52019-05-27 16:39:22 +0200758/* PyPreConfig.isolated=1, PyConfig.isolated=0 */
Victor Stinner6da20a42019-03-27 00:26:18 +0100759static int test_preinit_isolated1(void)
760{
Victor Stinner331a6a52019-05-27 16:39:22 +0200761 PyPreConfig preconfig;
Victor Stinner3c30a762019-10-01 10:56:37 +0200762 _PyPreConfig_InitCompatConfig(&preconfig);
Victor Stinner441b10c2019-09-28 04:28:35 +0200763
Victor Stinner6da20a42019-03-27 00:26:18 +0100764 preconfig.isolated = 1;
765
Victor Stinner3c30a762019-10-01 10:56:37 +0200766 PyStatus status = Py_PreInitialize(&preconfig);
Victor Stinner331a6a52019-05-27 16:39:22 +0200767 if (PyStatus_Exception(status)) {
768 Py_ExitStatusException(status);
Victor Stinner6da20a42019-03-27 00:26:18 +0100769 }
770
Victor Stinner331a6a52019-05-27 16:39:22 +0200771 PyConfig config;
Victor Stinner8462a492019-10-01 12:06:16 +0200772 _PyConfig_InitCompatConfig(&config);
Victor Stinner441b10c2019-09-28 04:28:35 +0200773
Victor Stinner67310022019-07-01 19:52:45 +0200774 config_set_program_name(&config);
Victor Stinnerbab0db62019-05-18 03:21:27 +0200775 set_all_env_vars();
Victor Stinner67310022019-07-01 19:52:45 +0200776 init_from_config_clear(&config);
777
Victor Stinner6da20a42019-03-27 00:26:18 +0100778 dump_config();
779 Py_Finalize();
780 return 0;
781}
782
783
Victor Stinner331a6a52019-05-27 16:39:22 +0200784/* PyPreConfig.isolated=0, PyConfig.isolated=1 */
Victor Stinner6da20a42019-03-27 00:26:18 +0100785static int test_preinit_isolated2(void)
786{
Victor Stinner331a6a52019-05-27 16:39:22 +0200787 PyPreConfig preconfig;
Victor Stinner3c30a762019-10-01 10:56:37 +0200788 _PyPreConfig_InitCompatConfig(&preconfig);
Victor Stinner441b10c2019-09-28 04:28:35 +0200789
Victor Stinner6da20a42019-03-27 00:26:18 +0100790 preconfig.isolated = 0;
791
Victor Stinner3c30a762019-10-01 10:56:37 +0200792 PyStatus status = Py_PreInitialize(&preconfig);
Victor Stinner331a6a52019-05-27 16:39:22 +0200793 if (PyStatus_Exception(status)) {
794 Py_ExitStatusException(status);
Victor Stinner6da20a42019-03-27 00:26:18 +0100795 }
796
Victor Stinner331a6a52019-05-27 16:39:22 +0200797 /* Test PyConfig.isolated=1 */
798 PyConfig config;
Victor Stinner8462a492019-10-01 12:06:16 +0200799 _PyConfig_InitCompatConfig(&config);
Victor Stinner6da20a42019-03-27 00:26:18 +0100800
801 Py_IsolatedFlag = 0;
802 config.isolated = 1;
803
Victor Stinner67310022019-07-01 19:52:45 +0200804 config_set_program_name(&config);
Victor Stinnerbab0db62019-05-18 03:21:27 +0200805 set_all_env_vars();
Victor Stinner67310022019-07-01 19:52:45 +0200806 init_from_config_clear(&config);
807
Victor Stinner6da20a42019-03-27 00:26:18 +0100808 dump_config();
809 Py_Finalize();
810 return 0;
811}
812
813
Victor Stinner6d1c4672019-05-20 11:02:00 +0200814static int test_preinit_dont_parse_argv(void)
815{
Victor Stinner331a6a52019-05-27 16:39:22 +0200816 PyPreConfig preconfig;
Victor Stinner3c30a762019-10-01 10:56:37 +0200817 PyPreConfig_InitIsolatedConfig(&preconfig);
Victor Stinner6d1c4672019-05-20 11:02:00 +0200818
819 preconfig.isolated = 0;
820
821 /* -X dev must be ignored by isolated preconfiguration */
822 wchar_t *argv[] = {L"python3",
823 L"-E",
824 L"-I",
825 L"-X", L"dev",
826 L"-X", L"utf8",
827 L"script.py"};
Victor Stinner3c30a762019-10-01 10:56:37 +0200828 PyStatus status = Py_PreInitializeFromArgs(&preconfig,
829 Py_ARRAY_LENGTH(argv), argv);
Victor Stinner331a6a52019-05-27 16:39:22 +0200830 if (PyStatus_Exception(status)) {
Victor Stinner67310022019-07-01 19:52:45 +0200831 Py_ExitStatusException(status);
Victor Stinner6d1c4672019-05-20 11:02:00 +0200832 }
833
Victor Stinner331a6a52019-05-27 16:39:22 +0200834 PyConfig config;
Victor Stinner8462a492019-10-01 12:06:16 +0200835 PyConfig_InitIsolatedConfig(&config);
Victor Stinner6d1c4672019-05-20 11:02:00 +0200836
837 config.isolated = 0;
838
839 /* Pre-initialize implicitly using argv: make sure that -X dev
840 is used to configure the allocation in preinitialization */
Victor Stinner67310022019-07-01 19:52:45 +0200841 config_set_argv(&config, Py_ARRAY_LENGTH(argv), argv);
842 config_set_program_name(&config);
843 init_from_config_clear(&config);
Victor Stinner6d1c4672019-05-20 11:02:00 +0200844
845 dump_config();
846 Py_Finalize();
847 return 0;
Victor Stinner6d1c4672019-05-20 11:02:00 +0200848}
849
850
851static int test_preinit_parse_argv(void)
852{
Victor Stinner331a6a52019-05-27 16:39:22 +0200853 PyConfig config;
Victor Stinner8462a492019-10-01 12:06:16 +0200854 PyConfig_InitPythonConfig(&config);
Victor Stinner6d1c4672019-05-20 11:02:00 +0200855
856 /* Pre-initialize implicitly using argv: make sure that -X dev
857 is used to configure the allocation in preinitialization */
858 wchar_t *argv[] = {L"python3", L"-X", L"dev", L"script.py"};
Victor Stinner67310022019-07-01 19:52:45 +0200859 config_set_argv(&config, Py_ARRAY_LENGTH(argv), argv);
860 config_set_program_name(&config);
861 init_from_config_clear(&config);
Victor Stinner6d1c4672019-05-20 11:02:00 +0200862
863 dump_config();
864 Py_Finalize();
865 return 0;
Victor Stinner6d1c4672019-05-20 11:02:00 +0200866}
867
868
869
870
Victor Stinnerbab0db62019-05-18 03:21:27 +0200871static void set_all_global_config_variables(void)
872{
873 Py_IsolatedFlag = 0;
874 Py_IgnoreEnvironmentFlag = 0;
875 Py_BytesWarningFlag = 2;
876 Py_InspectFlag = 1;
877 Py_InteractiveFlag = 1;
878 Py_OptimizeFlag = 1;
879 Py_DebugFlag = 1;
880 Py_VerboseFlag = 1;
881 Py_QuietFlag = 1;
882 Py_FrozenFlag = 0;
883 Py_UnbufferedStdioFlag = 1;
884 Py_NoSiteFlag = 1;
885 Py_DontWriteBytecodeFlag = 1;
886 Py_NoUserSiteDirectory = 1;
887#ifdef MS_WINDOWS
888 Py_LegacyWindowsStdioFlag = 1;
889#endif
890}
891
892
Victor Stinner6d1c4672019-05-20 11:02:00 +0200893static int check_preinit_isolated_config(int preinit)
Victor Stinner56b29b62018-07-26 18:57:56 +0200894{
Victor Stinner331a6a52019-05-27 16:39:22 +0200895 PyStatus status;
896 PyPreConfig *rt_preconfig;
Victor Stinnercab5d072019-05-17 19:01:14 +0200897
Victor Stinnerbab0db62019-05-18 03:21:27 +0200898 /* environment variables must be ignored */
899 set_all_env_vars();
900
901 /* global configuration variables must be ignored */
902 set_all_global_config_variables();
903
Victor Stinner6d1c4672019-05-20 11:02:00 +0200904 if (preinit) {
Victor Stinner331a6a52019-05-27 16:39:22 +0200905 PyPreConfig preconfig;
Victor Stinner3c30a762019-10-01 10:56:37 +0200906 PyPreConfig_InitIsolatedConfig(&preconfig);
Victor Stinnercab5d072019-05-17 19:01:14 +0200907
Victor Stinner331a6a52019-05-27 16:39:22 +0200908 status = Py_PreInitialize(&preconfig);
909 if (PyStatus_Exception(status)) {
910 Py_ExitStatusException(status);
Victor Stinner6d1c4672019-05-20 11:02:00 +0200911 }
912
913 rt_preconfig = &_PyRuntime.preconfig;
914 assert(rt_preconfig->isolated == 1);
915 assert(rt_preconfig->use_environment == 0);
Victor Stinnercab5d072019-05-17 19:01:14 +0200916 }
917
Victor Stinner331a6a52019-05-27 16:39:22 +0200918 PyConfig config;
Victor Stinner8462a492019-10-01 12:06:16 +0200919 PyConfig_InitIsolatedConfig(&config);
Victor Stinner441b10c2019-09-28 04:28:35 +0200920
Victor Stinner67310022019-07-01 19:52:45 +0200921 config_set_program_name(&config);
922 init_from_config_clear(&config);
Victor Stinner6d1c4672019-05-20 11:02:00 +0200923
924 rt_preconfig = &_PyRuntime.preconfig;
925 assert(rt_preconfig->isolated == 1);
926 assert(rt_preconfig->use_environment == 0);
927
Victor Stinnercab5d072019-05-17 19:01:14 +0200928 dump_config();
929 Py_Finalize();
930 return 0;
931}
932
933
Victor Stinner6d1c4672019-05-20 11:02:00 +0200934static int test_preinit_isolated_config(void)
935{
936 return check_preinit_isolated_config(1);
937}
938
939
940static int test_init_isolated_config(void)
941{
942 return check_preinit_isolated_config(0);
943}
944
945
946static int check_init_python_config(int preinit)
Victor Stinnercab5d072019-05-17 19:01:14 +0200947{
Victor Stinnerbab0db62019-05-18 03:21:27 +0200948 /* global configuration variables must be ignored */
949 set_all_global_config_variables();
950 Py_IsolatedFlag = 1;
951 Py_IgnoreEnvironmentFlag = 1;
952 Py_FrozenFlag = 1;
953 Py_UnbufferedStdioFlag = 1;
954 Py_NoSiteFlag = 1;
955 Py_DontWriteBytecodeFlag = 1;
956 Py_NoUserSiteDirectory = 1;
957#ifdef MS_WINDOWS
958 Py_LegacyWindowsStdioFlag = 1;
959#endif
960
Victor Stinner6d1c4672019-05-20 11:02:00 +0200961 if (preinit) {
Victor Stinner331a6a52019-05-27 16:39:22 +0200962 PyPreConfig preconfig;
Victor Stinner3c30a762019-10-01 10:56:37 +0200963 PyPreConfig_InitPythonConfig(&preconfig);
Victor Stinnercab5d072019-05-17 19:01:14 +0200964
Victor Stinner8462a492019-10-01 12:06:16 +0200965 PyStatus status = Py_PreInitialize(&preconfig);
Victor Stinner331a6a52019-05-27 16:39:22 +0200966 if (PyStatus_Exception(status)) {
967 Py_ExitStatusException(status);
Victor Stinner6d1c4672019-05-20 11:02:00 +0200968 }
Victor Stinnercab5d072019-05-17 19:01:14 +0200969 }
970
Victor Stinner331a6a52019-05-27 16:39:22 +0200971 PyConfig config;
Victor Stinner8462a492019-10-01 12:06:16 +0200972 PyConfig_InitPythonConfig(&config);
Victor Stinner441b10c2019-09-28 04:28:35 +0200973
Victor Stinner67310022019-07-01 19:52:45 +0200974 config_set_program_name(&config);
975 init_from_config_clear(&config);
Victor Stinnercab5d072019-05-17 19:01:14 +0200976
Victor Stinnercab5d072019-05-17 19:01:14 +0200977 dump_config();
978 Py_Finalize();
979 return 0;
980}
981
982
Victor Stinner6d1c4672019-05-20 11:02:00 +0200983static int test_preinit_python_config(void)
984{
985 return check_init_python_config(1);
986}
987
988
989static int test_init_python_config(void)
990{
991 return check_init_python_config(0);
992}
993
994
Victor Stinnerbab0db62019-05-18 03:21:27 +0200995static int test_init_dont_configure_locale(void)
Victor Stinnerbcfbbd72019-05-17 22:44:16 +0200996{
Victor Stinner331a6a52019-05-27 16:39:22 +0200997 PyPreConfig preconfig;
Victor Stinner3c30a762019-10-01 10:56:37 +0200998 PyPreConfig_InitPythonConfig(&preconfig);
Victor Stinner441b10c2019-09-28 04:28:35 +0200999
Victor Stinnerbcfbbd72019-05-17 22:44:16 +02001000 preconfig.configure_locale = 0;
1001 preconfig.coerce_c_locale = 1;
1002 preconfig.coerce_c_locale_warn = 1;
1003
Victor Stinner3c30a762019-10-01 10:56:37 +02001004 PyStatus status = Py_PreInitialize(&preconfig);
Victor Stinner331a6a52019-05-27 16:39:22 +02001005 if (PyStatus_Exception(status)) {
1006 Py_ExitStatusException(status);
Victor Stinnerbcfbbd72019-05-17 22:44:16 +02001007 }
1008
Victor Stinner331a6a52019-05-27 16:39:22 +02001009 PyConfig config;
Victor Stinner8462a492019-10-01 12:06:16 +02001010 PyConfig_InitPythonConfig(&config);
Victor Stinner441b10c2019-09-28 04:28:35 +02001011
Victor Stinner67310022019-07-01 19:52:45 +02001012 config_set_program_name(&config);
1013 init_from_config_clear(&config);
Victor Stinnerbcfbbd72019-05-17 22:44:16 +02001014
1015 dump_config();
1016 Py_Finalize();
1017 return 0;
1018}
1019
1020
Victor Stinnerbab0db62019-05-18 03:21:27 +02001021static int test_init_dev_mode(void)
Victor Stinnercab5d072019-05-17 19:01:14 +02001022{
Victor Stinner331a6a52019-05-27 16:39:22 +02001023 PyConfig config;
Victor Stinner8462a492019-10-01 12:06:16 +02001024 PyConfig_InitPythonConfig(&config);
Victor Stinner441b10c2019-09-28 04:28:35 +02001025
Victor Stinner56b29b62018-07-26 18:57:56 +02001026 putenv("PYTHONFAULTHANDLER=");
1027 putenv("PYTHONMALLOC=");
Victor Stinner20004952019-03-26 02:31:11 +01001028 config.dev_mode = 1;
Victor Stinner67310022019-07-01 19:52:45 +02001029 config_set_program_name(&config);
1030 init_from_config_clear(&config);
1031
Victor Stinner56b29b62018-07-26 18:57:56 +02001032 dump_config();
1033 Py_Finalize();
1034 return 0;
1035}
1036
Steve Dowerb82e17e2019-05-23 08:45:22 -07001037static PyObject *_open_code_hook(PyObject *path, void *data)
1038{
1039 if (PyUnicode_CompareWithASCIIString(path, "$$test-filename") == 0) {
1040 return PyLong_FromVoidPtr(data);
1041 }
1042 PyObject *io = PyImport_ImportModule("_io");
1043 if (!io) {
1044 return NULL;
1045 }
1046 return PyObject_CallMethod(io, "open", "Os", path, "rb");
1047}
1048
1049static int test_open_code_hook(void)
1050{
1051 int result = 0;
1052
1053 /* Provide a hook */
1054 result = PyFile_SetOpenCodeHook(_open_code_hook, &result);
1055 if (result) {
1056 printf("Failed to set hook\n");
1057 return 1;
1058 }
1059 /* A second hook should fail */
1060 result = PyFile_SetOpenCodeHook(_open_code_hook, &result);
1061 if (!result) {
1062 printf("Should have failed to set second hook\n");
1063 return 2;
1064 }
1065
1066 Py_IgnoreEnvironmentFlag = 0;
1067 _testembed_Py_Initialize();
1068 result = 0;
1069
1070 PyObject *r = PyFile_OpenCode("$$test-filename");
1071 if (!r) {
1072 PyErr_Print();
1073 result = 3;
1074 } else {
1075 void *cmp = PyLong_AsVoidPtr(r);
1076 Py_DECREF(r);
1077 if (cmp != &result) {
1078 printf("Did not get expected result from hook\n");
1079 result = 4;
1080 }
1081 }
1082
1083 if (!result) {
1084 PyObject *io = PyImport_ImportModule("_io");
1085 PyObject *r = io
1086 ? PyObject_CallMethod(io, "open_code", "s", "$$test-filename")
1087 : NULL;
1088 if (!r) {
1089 PyErr_Print();
1090 result = 5;
1091 } else {
1092 void *cmp = PyLong_AsVoidPtr(r);
1093 Py_DECREF(r);
1094 if (cmp != &result) {
1095 printf("Did not get expected result from hook\n");
1096 result = 6;
1097 }
1098 }
1099 Py_XDECREF(io);
1100 }
1101
1102 Py_Finalize();
1103 return result;
1104}
1105
1106static int _audit_hook(const char *event, PyObject *args, void *userdata)
1107{
1108 if (strcmp(event, "_testembed.raise") == 0) {
1109 PyErr_SetString(PyExc_RuntimeError, "Intentional error");
1110 return -1;
1111 } else if (strcmp(event, "_testembed.set") == 0) {
1112 if (!PyArg_ParseTuple(args, "n", userdata)) {
1113 return -1;
1114 }
1115 return 0;
1116 }
1117 return 0;
1118}
1119
1120static int _test_audit(Py_ssize_t setValue)
1121{
1122 Py_ssize_t sawSet = 0;
1123
1124 Py_IgnoreEnvironmentFlag = 0;
1125 PySys_AddAuditHook(_audit_hook, &sawSet);
1126 _testembed_Py_Initialize();
1127
1128 if (PySys_Audit("_testembed.raise", NULL) == 0) {
1129 printf("No error raised");
1130 return 1;
1131 }
1132 if (PySys_Audit("_testembed.nop", NULL) != 0) {
1133 printf("Nop event failed");
1134 /* Exception from above may still remain */
1135 PyErr_Clear();
1136 return 2;
1137 }
1138 if (!PyErr_Occurred()) {
1139 printf("Exception not preserved");
1140 return 3;
1141 }
1142 PyErr_Clear();
1143
1144 if (PySys_Audit("_testembed.set", "n", setValue) != 0) {
1145 PyErr_Print();
1146 printf("Set event failed");
1147 return 4;
1148 }
1149
1150 if (sawSet != 42) {
1151 printf("Failed to see *userData change\n");
1152 return 5;
1153 }
1154 return 0;
1155}
1156
1157static int test_audit(void)
1158{
1159 int result = _test_audit(42);
1160 Py_Finalize();
1161 return result;
1162}
1163
1164static volatile int _audit_subinterpreter_interpreter_count = 0;
1165
1166static int _audit_subinterpreter_hook(const char *event, PyObject *args, void *userdata)
1167{
1168 printf("%s\n", event);
1169 if (strcmp(event, "cpython.PyInterpreterState_New") == 0) {
1170 _audit_subinterpreter_interpreter_count += 1;
1171 }
1172 return 0;
1173}
1174
1175static int test_audit_subinterpreter(void)
1176{
Steve Dowerb82e17e2019-05-23 08:45:22 -07001177 Py_IgnoreEnvironmentFlag = 0;
1178 PySys_AddAuditHook(_audit_subinterpreter_hook, NULL);
1179 _testembed_Py_Initialize();
1180
Pablo Galindocccc11b2019-05-24 00:53:21 +01001181 Py_NewInterpreter();
1182 Py_NewInterpreter();
1183 Py_NewInterpreter();
Steve Dowerb82e17e2019-05-23 08:45:22 -07001184
1185 Py_Finalize();
1186
1187 switch (_audit_subinterpreter_interpreter_count) {
1188 case 3: return 0;
1189 case 0: return -1;
1190 default: return _audit_subinterpreter_interpreter_count;
1191 }
1192}
Victor Stinner56b29b62018-07-26 18:57:56 +02001193
Steve Dowere226e832019-07-01 16:03:53 -07001194typedef struct {
1195 const char* expected;
1196 int exit;
1197} AuditRunCommandTest;
1198
1199static int _audit_hook_run(const char *eventName, PyObject *args, void *userData)
1200{
1201 AuditRunCommandTest *test = (AuditRunCommandTest*)userData;
1202 if (strcmp(eventName, test->expected)) {
1203 return 0;
1204 }
1205
1206 if (test->exit) {
1207 PyObject *msg = PyUnicode_FromFormat("detected %s(%R)", eventName, args);
1208 if (msg) {
1209 printf("%s\n", PyUnicode_AsUTF8(msg));
1210 Py_DECREF(msg);
1211 }
1212 exit(test->exit);
1213 }
1214
1215 PyErr_Format(PyExc_RuntimeError, "detected %s(%R)", eventName, args);
1216 return -1;
1217}
1218
1219static int test_audit_run_command(void)
1220{
1221 AuditRunCommandTest test = {"cpython.run_command"};
Victor Stinnerbb6bf7d2019-09-24 18:21:02 +02001222 wchar_t *argv[] = {PROGRAM_NAME, L"-c", L"pass"};
Steve Dowere226e832019-07-01 16:03:53 -07001223
1224 Py_IgnoreEnvironmentFlag = 0;
1225 PySys_AddAuditHook(_audit_hook_run, (void*)&test);
1226
1227 return Py_Main(Py_ARRAY_LENGTH(argv), argv);
1228}
1229
1230static int test_audit_run_file(void)
1231{
1232 AuditRunCommandTest test = {"cpython.run_file"};
Victor Stinnerbb6bf7d2019-09-24 18:21:02 +02001233 wchar_t *argv[] = {PROGRAM_NAME, L"filename.py"};
Steve Dowere226e832019-07-01 16:03:53 -07001234
1235 Py_IgnoreEnvironmentFlag = 0;
1236 PySys_AddAuditHook(_audit_hook_run, (void*)&test);
1237
1238 return Py_Main(Py_ARRAY_LENGTH(argv), argv);
1239}
1240
1241static int run_audit_run_test(int argc, wchar_t **argv, void *test)
1242{
Steve Dowere226e832019-07-01 16:03:53 -07001243 PyConfig config;
Victor Stinner8462a492019-10-01 12:06:16 +02001244 PyConfig_InitPythonConfig(&config);
Victor Stinner441b10c2019-09-28 04:28:35 +02001245
Steve Dowere226e832019-07-01 16:03:53 -07001246 config.argv.length = argc;
1247 config.argv.items = argv;
1248 config.parse_argv = 1;
1249 config.program_name = argv[0];
1250 config.interactive = 1;
1251 config.isolated = 0;
1252 config.use_environment = 1;
1253 config.quiet = 1;
1254
1255 PySys_AddAuditHook(_audit_hook_run, test);
1256
Victor Stinner8462a492019-10-01 12:06:16 +02001257 PyStatus status = Py_InitializeFromConfig(&config);
Steve Dowere226e832019-07-01 16:03:53 -07001258 if (PyStatus_Exception(status)) {
1259 Py_ExitStatusException(status);
1260 }
1261
1262 return Py_RunMain();
1263}
1264
1265static int test_audit_run_interactivehook(void)
1266{
1267 AuditRunCommandTest test = {"cpython.run_interactivehook", 10};
Victor Stinnerbb6bf7d2019-09-24 18:21:02 +02001268 wchar_t *argv[] = {PROGRAM_NAME};
Steve Dowere226e832019-07-01 16:03:53 -07001269 return run_audit_run_test(Py_ARRAY_LENGTH(argv), argv, &test);
1270}
1271
1272static int test_audit_run_startup(void)
1273{
1274 AuditRunCommandTest test = {"cpython.run_startup", 10};
Victor Stinnerbb6bf7d2019-09-24 18:21:02 +02001275 wchar_t *argv[] = {PROGRAM_NAME};
Steve Dowere226e832019-07-01 16:03:53 -07001276 return run_audit_run_test(Py_ARRAY_LENGTH(argv), argv, &test);
1277}
1278
1279static int test_audit_run_stdin(void)
1280{
1281 AuditRunCommandTest test = {"cpython.run_stdin"};
Victor Stinnerbb6bf7d2019-09-24 18:21:02 +02001282 wchar_t *argv[] = {PROGRAM_NAME};
Steve Dowere226e832019-07-01 16:03:53 -07001283 return run_audit_run_test(Py_ARRAY_LENGTH(argv), argv, &test);
1284}
1285
Victor Stinner91c99872019-05-14 22:01:51 +02001286static int test_init_read_set(void)
1287{
Victor Stinner331a6a52019-05-27 16:39:22 +02001288 PyStatus status;
1289 PyConfig config;
Victor Stinner8462a492019-10-01 12:06:16 +02001290 PyConfig_InitPythonConfig(&config);
Victor Stinner91c99872019-05-14 22:01:51 +02001291
Victor Stinner331a6a52019-05-27 16:39:22 +02001292 status = PyConfig_SetBytesString(&config, &config.program_name,
Victor Stinner6d1c4672019-05-20 11:02:00 +02001293 "./init_read_set");
Victor Stinner331a6a52019-05-27 16:39:22 +02001294 if (PyStatus_Exception(status)) {
Victor Stinner91c99872019-05-14 22:01:51 +02001295 goto fail;
1296 }
1297
Victor Stinner331a6a52019-05-27 16:39:22 +02001298 status = PyConfig_Read(&config);
1299 if (PyStatus_Exception(status)) {
Victor Stinner91c99872019-05-14 22:01:51 +02001300 goto fail;
1301 }
1302
Victor Stinner3842f292019-08-23 16:57:54 +01001303 status = PyWideStringList_Insert(&config.module_search_paths,
1304 1, L"test_path_insert1");
1305 if (PyStatus_Exception(status)) {
1306 goto fail;
1307 }
1308
Victor Stinner331a6a52019-05-27 16:39:22 +02001309 status = PyWideStringList_Append(&config.module_search_paths,
Victor Stinner3842f292019-08-23 16:57:54 +01001310 L"test_path_append");
Victor Stinner331a6a52019-05-27 16:39:22 +02001311 if (PyStatus_Exception(status)) {
Victor Stinner91c99872019-05-14 22:01:51 +02001312 goto fail;
1313 }
1314
Victor Stinner331a6a52019-05-27 16:39:22 +02001315 /* override executable computed by PyConfig_Read() */
Victor Stinner67310022019-07-01 19:52:45 +02001316 config_set_string(&config, &config.executable, L"my_executable");
1317 init_from_config_clear(&config);
Victor Stinner91c99872019-05-14 22:01:51 +02001318
Victor Stinner91c99872019-05-14 22:01:51 +02001319 dump_config();
1320 Py_Finalize();
1321 return 0;
1322
1323fail:
Victor Stinner331a6a52019-05-27 16:39:22 +02001324 Py_ExitStatusException(status);
Victor Stinner91c99872019-05-14 22:01:51 +02001325}
1326
1327
Victor Stinner120b7072019-08-23 18:03:08 +01001328static int test_init_sys_add(void)
1329{
1330 PySys_AddXOption(L"sysadd_xoption");
1331 PySys_AddXOption(L"faulthandler");
1332 PySys_AddWarnOption(L"ignore:::sysadd_warnoption");
1333
1334 PyConfig config;
Victor Stinner8462a492019-10-01 12:06:16 +02001335 PyConfig_InitPythonConfig(&config);
Victor Stinner120b7072019-08-23 18:03:08 +01001336
1337 wchar_t* argv[] = {
1338 L"python3",
1339 L"-W",
1340 L"ignore:::cmdline_warnoption",
1341 L"-X",
1342 L"cmdline_xoption",
1343 };
1344 config_set_argv(&config, Py_ARRAY_LENGTH(argv), argv);
1345 config.parse_argv = 1;
1346
Victor Stinner8462a492019-10-01 12:06:16 +02001347 PyStatus status;
Victor Stinner120b7072019-08-23 18:03:08 +01001348 status = PyWideStringList_Append(&config.xoptions,
1349 L"config_xoption");
1350 if (PyStatus_Exception(status)) {
1351 goto fail;
1352 }
1353
1354 status = PyWideStringList_Append(&config.warnoptions,
1355 L"ignore:::config_warnoption");
1356 if (PyStatus_Exception(status)) {
1357 goto fail;
1358 }
1359
1360 config_set_program_name(&config);
1361 init_from_config_clear(&config);
1362
1363 dump_config();
1364 Py_Finalize();
1365 return 0;
1366
1367fail:
1368 PyConfig_Clear(&config);
1369 Py_ExitStatusException(status);
1370}
1371
1372
Victor Stinnerbb6bf7d2019-09-24 18:21:02 +02001373static int test_init_setpath(void)
1374{
Victor Stinnerbb6bf7d2019-09-24 18:21:02 +02001375 char *env = getenv("TESTPATH");
1376 if (!env) {
1377 fprintf(stderr, "missing TESTPATH env var\n");
1378 return 1;
1379 }
1380 wchar_t *path = Py_DecodeLocale(env, NULL);
1381 if (path == NULL) {
1382 fprintf(stderr, "failed to decode TESTPATH\n");
1383 return 1;
1384 }
1385 Py_SetPath(path);
1386 PyMem_RawFree(path);
1387 putenv("TESTPATH=");
1388
1389 Py_Initialize();
1390 dump_config();
1391 Py_Finalize();
1392 return 0;
1393}
1394
1395
Victor Stinner8bf39b62019-09-26 02:22:35 +02001396static int test_init_setpath_config(void)
Victor Stinnerbb6bf7d2019-09-24 18:21:02 +02001397{
Victor Stinner49d99f02019-09-26 04:01:49 +02001398 PyPreConfig preconfig;
Victor Stinner3c30a762019-10-01 10:56:37 +02001399 PyPreConfig_InitPythonConfig(&preconfig);
Victor Stinner49d99f02019-09-26 04:01:49 +02001400
1401 /* Explicitly preinitializes with Python preconfiguration to avoid
1402 Py_SetPath() implicit preinitialization with compat preconfiguration. */
Victor Stinner3c30a762019-10-01 10:56:37 +02001403 PyStatus status = Py_PreInitialize(&preconfig);
Victor Stinner49d99f02019-09-26 04:01:49 +02001404 if (PyStatus_Exception(status)) {
1405 Py_ExitStatusException(status);
1406 }
1407
Victor Stinner8bf39b62019-09-26 02:22:35 +02001408 char *env = getenv("TESTPATH");
1409 if (!env) {
1410 fprintf(stderr, "missing TESTPATH env var\n");
1411 return 1;
Victor Stinnerbb6bf7d2019-09-24 18:21:02 +02001412 }
Victor Stinner8bf39b62019-09-26 02:22:35 +02001413 wchar_t *path = Py_DecodeLocale(env, NULL);
1414 if (path == NULL) {
1415 fprintf(stderr, "failed to decode TESTPATH\n");
1416 return 1;
1417 }
1418 Py_SetPath(path);
1419 PyMem_RawFree(path);
1420 putenv("TESTPATH=");
Victor Stinnerbb6bf7d2019-09-24 18:21:02 +02001421
Victor Stinner8bf39b62019-09-26 02:22:35 +02001422 PyConfig config;
Victor Stinner8462a492019-10-01 12:06:16 +02001423 PyConfig_InitPythonConfig(&config);
Victor Stinnerbb6bf7d2019-09-24 18:21:02 +02001424
Victor Stinner8bf39b62019-09-26 02:22:35 +02001425 config_set_string(&config, &config.program_name, L"conf_program_name");
1426 config_set_string(&config, &config.executable, L"conf_executable");
1427 init_from_config_clear(&config);
Victor Stinnerbb6bf7d2019-09-24 18:21:02 +02001428
Victor Stinner8bf39b62019-09-26 02:22:35 +02001429 dump_config();
1430 Py_Finalize();
Victor Stinnerbb6bf7d2019-09-24 18:21:02 +02001431 return 0;
1432}
1433
1434
1435static int test_init_setpythonhome(void)
1436{
1437 char *env = getenv("TESTHOME");
1438 if (!env) {
1439 fprintf(stderr, "missing TESTHOME env var\n");
1440 return 1;
1441 }
1442 wchar_t *home = Py_DecodeLocale(env, NULL);
1443 if (home == NULL) {
1444 fprintf(stderr, "failed to decode TESTHOME\n");
1445 return 1;
1446 }
1447 Py_SetPythonHome(home);
1448 PyMem_RawFree(home);
1449 putenv("TESTHOME=");
1450
Victor Stinnerbb6bf7d2019-09-24 18:21:02 +02001451 Py_Initialize();
1452 dump_config();
1453 Py_Finalize();
1454 return 0;
1455}
1456
1457
Victor Stinnerfb4ae152019-09-30 01:40:17 +02001458static int test_init_warnoptions(void)
1459{
Victor Stinnerfb4ae152019-09-30 01:40:17 +02001460 putenv("PYTHONWARNINGS=ignore:::env1,ignore:::env2");
1461
1462 PySys_AddWarnOption(L"ignore:::PySys_AddWarnOption1");
1463 PySys_AddWarnOption(L"ignore:::PySys_AddWarnOption2");
1464
1465 PyConfig config;
Victor Stinner8462a492019-10-01 12:06:16 +02001466 PyConfig_InitPythonConfig(&config);
Victor Stinnerfb4ae152019-09-30 01:40:17 +02001467
1468 config.dev_mode = 1;
1469 config.bytes_warning = 1;
1470
1471 config_set_program_name(&config);
1472
Victor Stinner8462a492019-10-01 12:06:16 +02001473 PyStatus status;
Victor Stinnerfb4ae152019-09-30 01:40:17 +02001474 status = PyWideStringList_Append(&config.warnoptions,
1475 L"ignore:::PyConfig_BeforeRead");
1476 if (PyStatus_Exception(status)) {
1477 Py_ExitStatusException(status);
1478 }
1479
1480 wchar_t* argv[] = {
1481 L"python3",
1482 L"-Wignore:::cmdline1",
1483 L"-Wignore:::cmdline2"};
1484 config_set_argv(&config, Py_ARRAY_LENGTH(argv), argv);
1485 config.parse_argv = 1;
1486
1487 status = PyConfig_Read(&config);
1488 if (PyStatus_Exception(status)) {
1489 Py_ExitStatusException(status);
1490 }
1491
1492 status = PyWideStringList_Append(&config.warnoptions,
1493 L"ignore:::PyConfig_AfterRead");
1494 if (PyStatus_Exception(status)) {
1495 Py_ExitStatusException(status);
1496 }
1497
1498 status = PyWideStringList_Insert(&config.warnoptions,
1499 0, L"ignore:::PyConfig_Insert0");
1500 if (PyStatus_Exception(status)) {
1501 Py_ExitStatusException(status);
1502 }
1503
1504 init_from_config_clear(&config);
1505 dump_config();
1506 Py_Finalize();
1507 return 0;
1508}
1509
1510
Victor Stinner331a6a52019-05-27 16:39:22 +02001511static void configure_init_main(PyConfig *config)
Victor Stinner9ef5dca2019-05-16 17:38:16 +02001512{
Victor Stinner67310022019-07-01 19:52:45 +02001513 wchar_t* argv[] = {
1514 L"python3", L"-c",
1515 (L"import _testinternalcapi, json; "
1516 L"print(json.dumps(_testinternalcapi.get_configs()))"),
1517 L"arg2"};
1518
Victor Stinnercab5d072019-05-17 19:01:14 +02001519 config->parse_argv = 1;
Victor Stinner67310022019-07-01 19:52:45 +02001520
1521 config_set_argv(config, Py_ARRAY_LENGTH(argv), argv);
1522 config_set_string(config, &config->program_name, L"./python3");
Victor Stinner9ef5dca2019-05-16 17:38:16 +02001523}
1524
1525
1526static int test_init_run_main(void)
Victor Stinner2f549082019-03-29 15:13:46 +01001527{
Victor Stinner331a6a52019-05-27 16:39:22 +02001528 PyConfig config;
Victor Stinner8462a492019-10-01 12:06:16 +02001529 PyConfig_InitPythonConfig(&config);
Victor Stinner441b10c2019-09-28 04:28:35 +02001530
Victor Stinner9ef5dca2019-05-16 17:38:16 +02001531 configure_init_main(&config);
Victor Stinner67310022019-07-01 19:52:45 +02001532 init_from_config_clear(&config);
Victor Stinner2f549082019-03-29 15:13:46 +01001533
Victor Stinner331a6a52019-05-27 16:39:22 +02001534 return Py_RunMain();
Victor Stinner2f549082019-03-29 15:13:46 +01001535}
1536
1537
Victor Stinner9ef5dca2019-05-16 17:38:16 +02001538static int test_init_main(void)
1539{
Victor Stinner331a6a52019-05-27 16:39:22 +02001540 PyConfig config;
Victor Stinner8462a492019-10-01 12:06:16 +02001541 PyConfig_InitPythonConfig(&config);
Victor Stinner6d1c4672019-05-20 11:02:00 +02001542
Victor Stinner9ef5dca2019-05-16 17:38:16 +02001543 configure_init_main(&config);
1544 config._init_main = 0;
Victor Stinner67310022019-07-01 19:52:45 +02001545 init_from_config_clear(&config);
Victor Stinner9ef5dca2019-05-16 17:38:16 +02001546
1547 /* sys.stdout don't exist yet: it is created by _Py_InitializeMain() */
1548 int res = PyRun_SimpleString(
1549 "import sys; "
1550 "print('Run Python code before _Py_InitializeMain', "
1551 "file=sys.stderr)");
1552 if (res < 0) {
1553 exit(1);
1554 }
1555
Victor Stinner8462a492019-10-01 12:06:16 +02001556 PyStatus status = _Py_InitializeMain();
Victor Stinner331a6a52019-05-27 16:39:22 +02001557 if (PyStatus_Exception(status)) {
1558 Py_ExitStatusException(status);
Victor Stinner9ef5dca2019-05-16 17:38:16 +02001559 }
1560
Victor Stinner331a6a52019-05-27 16:39:22 +02001561 return Py_RunMain();
Victor Stinner9ef5dca2019-05-16 17:38:16 +02001562}
1563
1564
1565static int test_run_main(void)
Victor Stinner5eb8b072019-05-15 02:12:48 +02001566{
Victor Stinner331a6a52019-05-27 16:39:22 +02001567 PyConfig config;
Victor Stinner8462a492019-10-01 12:06:16 +02001568 PyConfig_InitPythonConfig(&config);
Victor Stinner5eb8b072019-05-15 02:12:48 +02001569
1570 wchar_t *argv[] = {L"python3", L"-c",
Victor Stinner9ef5dca2019-05-16 17:38:16 +02001571 (L"import sys; "
Victor Stinner331a6a52019-05-27 16:39:22 +02001572 L"print(f'Py_RunMain(): sys.argv={sys.argv}')"),
Victor Stinner5eb8b072019-05-15 02:12:48 +02001573 L"arg2"};
Victor Stinner67310022019-07-01 19:52:45 +02001574 config_set_argv(&config, Py_ARRAY_LENGTH(argv), argv);
1575 config_set_string(&config, &config.program_name, L"./python3");
1576 init_from_config_clear(&config);
Victor Stinner6d1c4672019-05-20 11:02:00 +02001577
Victor Stinner331a6a52019-05-27 16:39:22 +02001578 return Py_RunMain();
Victor Stinner5eb8b072019-05-15 02:12:48 +02001579}
1580
1581
Steve Dowerea74f0c2017-01-01 20:25:03 -08001582/* *********************************************************
1583 * List of test cases and the function that implements it.
Serhiy Storchaka13ad3b72017-09-14 09:38:36 +03001584 *
Steve Dowerea74f0c2017-01-01 20:25:03 -08001585 * Names are compared case-sensitively with the first
1586 * argument. If no match is found, or no first argument was
1587 * provided, the names of all test cases are printed and
1588 * the exit code will be -1.
1589 *
1590 * The int returned from test functions is used as the exit
1591 * code, and test_capi treats all non-zero exit codes as a
Serhiy Storchaka13ad3b72017-09-14 09:38:36 +03001592 * failed test.
Steve Dowerea74f0c2017-01-01 20:25:03 -08001593 *********************************************************/
1594struct TestCase
1595{
1596 const char *name;
1597 int (*func)(void);
1598};
1599
1600static struct TestCase TestCases[] = {
Victor Stinner5edcf262019-05-23 00:57:57 +02001601 {"test_forced_io_encoding", test_forced_io_encoding},
1602 {"test_repeated_init_and_subinterpreters", test_repeated_init_and_subinterpreters},
1603 {"test_pre_initialization_api", test_pre_initialization_api},
1604 {"test_pre_initialization_sys_options", test_pre_initialization_sys_options},
1605 {"test_bpo20891", test_bpo20891},
1606 {"test_initialize_twice", test_initialize_twice},
1607 {"test_initialize_pymain", test_initialize_pymain},
1608 {"test_init_initialize_config", test_init_initialize_config},
1609 {"test_preinit_compat_config", test_preinit_compat_config},
1610 {"test_init_compat_config", test_init_compat_config},
1611 {"test_init_global_config", test_init_global_config},
1612 {"test_init_from_config", test_init_from_config},
1613 {"test_init_parse_argv", test_init_parse_argv},
1614 {"test_init_dont_parse_argv", test_init_dont_parse_argv},
Victor Stinner20e1e252019-05-23 04:12:27 +02001615 {"test_init_compat_env", test_init_compat_env},
1616 {"test_init_python_env", test_init_python_env},
Victor Stinner5edcf262019-05-23 00:57:57 +02001617 {"test_init_env_dev_mode", test_init_env_dev_mode},
1618 {"test_init_env_dev_mode_alloc", test_init_env_dev_mode_alloc},
1619 {"test_init_dont_configure_locale", test_init_dont_configure_locale},
1620 {"test_init_dev_mode", test_init_dev_mode},
1621 {"test_init_isolated_flag", test_init_isolated_flag},
1622 {"test_preinit_isolated_config", test_preinit_isolated_config},
1623 {"test_init_isolated_config", test_init_isolated_config},
1624 {"test_preinit_python_config", test_preinit_python_config},
1625 {"test_init_python_config", test_init_python_config},
1626 {"test_preinit_isolated1", test_preinit_isolated1},
1627 {"test_preinit_isolated2", test_preinit_isolated2},
1628 {"test_preinit_parse_argv", test_preinit_parse_argv},
1629 {"test_preinit_dont_parse_argv", test_preinit_dont_parse_argv},
1630 {"test_init_read_set", test_init_read_set},
1631 {"test_init_run_main", test_init_run_main},
1632 {"test_init_main", test_init_main},
Victor Stinner120b7072019-08-23 18:03:08 +01001633 {"test_init_sys_add", test_init_sys_add},
Victor Stinnerbb6bf7d2019-09-24 18:21:02 +02001634 {"test_init_setpath", test_init_setpath},
Victor Stinner8bf39b62019-09-26 02:22:35 +02001635 {"test_init_setpath_config", test_init_setpath_config},
Victor Stinnerbb6bf7d2019-09-24 18:21:02 +02001636 {"test_init_setpythonhome", test_init_setpythonhome},
Victor Stinnerfb4ae152019-09-30 01:40:17 +02001637 {"test_init_warnoptions", test_init_warnoptions},
Victor Stinner5edcf262019-05-23 00:57:57 +02001638 {"test_run_main", test_run_main},
Victor Stinnerbb6bf7d2019-09-24 18:21:02 +02001639
Steve Dowerb82e17e2019-05-23 08:45:22 -07001640 {"test_open_code_hook", test_open_code_hook},
1641 {"test_audit", test_audit},
1642 {"test_audit_subinterpreter", test_audit_subinterpreter},
Steve Dowere226e832019-07-01 16:03:53 -07001643 {"test_audit_run_command", test_audit_run_command},
1644 {"test_audit_run_file", test_audit_run_file},
1645 {"test_audit_run_interactivehook", test_audit_run_interactivehook},
1646 {"test_audit_run_startup", test_audit_run_startup},
1647 {"test_audit_run_stdin", test_audit_run_stdin},
Victor Stinner5edcf262019-05-23 00:57:57 +02001648 {NULL, NULL}
Steve Dowerea74f0c2017-01-01 20:25:03 -08001649};
1650
Nick Coghlan7d270ee2013-10-17 22:35:35 +10001651int main(int argc, char *argv[])
1652{
Nick Coghlan7d270ee2013-10-17 22:35:35 +10001653 if (argc > 1) {
Steve Dowerea74f0c2017-01-01 20:25:03 -08001654 for (struct TestCase *tc = TestCases; tc && tc->name; tc++) {
1655 if (strcmp(argv[1], tc->name) == 0)
1656 return (*tc->func)();
1657 }
Nick Coghlan7d270ee2013-10-17 22:35:35 +10001658 }
Steve Dowerea74f0c2017-01-01 20:25:03 -08001659
1660 /* No match found, or no test name provided, so display usage */
1661 printf("Python " PY_VERSION " _testembed executable for embedded interpreter tests\n"
Nick Coghlanbc77eff2018-03-25 20:44:30 +10001662 "Normally executed via 'EmbeddingTests' in Lib/test/test_embed.py\n\n"
Steve Dowerea74f0c2017-01-01 20:25:03 -08001663 "Usage: %s TESTNAME\n\nAll available tests:\n", argv[0]);
1664 for (struct TestCase *tc = TestCases; tc && tc->name; tc++) {
1665 printf(" %s\n", tc->name);
1666 }
1667
Nick Coghlanbc77eff2018-03-25 20:44:30 +10001668 /* Non-zero exit code will cause test_embed.py tests to fail.
Steve Dowerea74f0c2017-01-01 20:25:03 -08001669 This is intentional. */
1670 return -1;
Antoine Pitrou8e605772011-04-25 21:21:07 +02001671}