@@ -22,7 +22,7 @@ char **main_argv;
2222/*********************************************************
2323 * Embedded interpreter tests that need a custom exe
2424 *
25- * Executed via 'EmbeddingTests' in Lib/test/test_capi .py
25+ * Executed via Lib/test/test_embed .py
2626 *********************************************************/
2727
2828// Use to display the usage
@@ -73,14 +73,20 @@ static void init_from_config_clear(PyConfig *config)
7373}
7474
7575
76- static void _testembed_Py_Initialize (void )
76+ static void _testembed_Py_InitializeFromConfig (void )
7777{
7878 PyConfig config ;
7979 _PyConfig_InitCompatConfig (& config );
8080 config_set_program_name (& config );
8181 init_from_config_clear (& config );
8282}
8383
84+ static void _testembed_Py_Initialize (void )
85+ {
86+ Py_SetProgramName (PROGRAM_NAME );
87+ Py_Initialize ();
88+ }
89+
8490
8591/*****************************************************
8692 * Test repeated initialisation and subinterpreters
@@ -110,7 +116,7 @@ static int test_repeated_init_and_subinterpreters(void)
110116
111117 for (int i = 1 ; i <= INIT_LOOPS ; i ++ ) {
112118 printf ("--- Pass %d ---\n" , i );
113- _testembed_Py_Initialize ();
119+ _testembed_Py_InitializeFromConfig ();
114120 mainstate = PyThreadState_Get ();
115121
116122 PyEval_ReleaseThread (mainstate );
@@ -168,7 +174,7 @@ static int test_repeated_init_exec(void)
168174 fprintf (stderr , "--- Loop #%d ---\n" , i );
169175 fflush (stderr );
170176
171- _testembed_Py_Initialize ();
177+ _testembed_Py_InitializeFromConfig ();
172178 int err = PyRun_SimpleString (code );
173179 Py_Finalize ();
174180 if (err ) {
@@ -178,6 +184,23 @@ static int test_repeated_init_exec(void)
178184 return 0 ;
179185}
180186
187+ /****************************************************************************
188+ * Test the Py_Initialize(Ex) convenience/compatibility wrappers
189+ ***************************************************************************/
190+ // This is here to help ensure there are no wrapper resource leaks (gh-96853)
191+ static int test_repeated_simple_init (void )
192+ {
193+ for (int i = 1 ; i <= INIT_LOOPS ; i ++ ) {
194+ fprintf (stderr , "--- Loop #%d ---\n" , i );
195+ fflush (stderr );
196+
197+ _testembed_Py_Initialize ();
198+ Py_Finalize ();
199+ printf ("Finalized\n" ); // Give test_embed some output to check
200+ }
201+ return 0 ;
202+ }
203+
181204
182205/*****************************************************
183206 * Test forcing a particular IO encoding
@@ -199,7 +222,7 @@ static void check_stdio_details(const char *encoding, const char * errors)
199222 fflush (stdout );
200223 /* Force the given IO encoding */
201224 Py_SetStandardStreamEncoding (encoding , errors );
202- _testembed_Py_Initialize ();
225+ _testembed_Py_InitializeFromConfig ();
203226 PyRun_SimpleString (
204227 "import sys;"
205228 "print('stdin: {0.encoding}:{0.errors}'.format(sys.stdin));"
@@ -308,7 +331,7 @@ static int test_pre_initialization_sys_options(void)
308331 dynamic_xoption = NULL ;
309332
310333 _Py_EMBED_PREINIT_CHECK ("Initializing interpreter\n" );
311- _testembed_Py_Initialize ();
334+ _testembed_Py_InitializeFromConfig ();
312335 _Py_EMBED_PREINIT_CHECK ("Check sys module contents\n" );
313336 PyRun_SimpleString ("import sys; "
314337 "print('sys.warnoptions:', sys.warnoptions); "
@@ -352,7 +375,7 @@ static int test_bpo20891(void)
352375 return 1 ;
353376 }
354377
355- _testembed_Py_Initialize ();
378+ _testembed_Py_InitializeFromConfig ();
356379
357380 unsigned long thrd = PyThread_start_new_thread (bpo20891_thread , & lock );
358381 if (thrd == PYTHREAD_INVALID_THREAD_ID ) {
@@ -375,7 +398,7 @@ static int test_bpo20891(void)
375398
376399static int test_initialize_twice (void )
377400{
378- _testembed_Py_Initialize ();
401+ _testembed_Py_InitializeFromConfig ();
379402
380403 /* bpo-33932: Calling Py_Initialize() twice should do nothing
381404 * (and not crash!). */
@@ -393,7 +416,7 @@ static int test_initialize_pymain(void)
393416 L"print(f'Py_Main() after Py_Initialize: "
394417 L"sys.argv={sys.argv}')" ),
395418 L"arg2" };
396- _testembed_Py_Initialize ();
419+ _testembed_Py_InitializeFromConfig ();
397420
398421 /* bpo-34008: Calling Py_Main() after Py_Initialize() must not crash */
399422 Py_Main (Py_ARRAY_LENGTH (argv ), argv );
@@ -416,7 +439,7 @@ dump_config(void)
416439
417440static int test_init_initialize_config (void )
418441{
419- _testembed_Py_Initialize ();
442+ _testembed_Py_InitializeFromConfig ();
420443 dump_config ();
421444 Py_Finalize ();
422445 return 0 ;
@@ -767,7 +790,7 @@ static int test_init_compat_env(void)
767790 /* Test initialization from environment variables */
768791 Py_IgnoreEnvironmentFlag = 0 ;
769792 set_all_env_vars ();
770- _testembed_Py_Initialize ();
793+ _testembed_Py_InitializeFromConfig ();
771794 dump_config ();
772795 Py_Finalize ();
773796 return 0 ;
@@ -803,7 +826,7 @@ static int test_init_env_dev_mode(void)
803826 /* Test initialization from environment variables */
804827 Py_IgnoreEnvironmentFlag = 0 ;
805828 set_all_env_vars_dev_mode ();
806- _testembed_Py_Initialize ();
829+ _testembed_Py_InitializeFromConfig ();
807830 dump_config ();
808831 Py_Finalize ();
809832 return 0 ;
@@ -816,7 +839,7 @@ static int test_init_env_dev_mode_alloc(void)
816839 Py_IgnoreEnvironmentFlag = 0 ;
817840 set_all_env_vars_dev_mode ();
818841 putenv ("PYTHONMALLOC=malloc" );
819- _testembed_Py_Initialize ();
842+ _testembed_Py_InitializeFromConfig ();
820843 dump_config ();
821844 Py_Finalize ();
822845 return 0 ;
@@ -1156,7 +1179,7 @@ static int test_open_code_hook(void)
11561179 }
11571180
11581181 Py_IgnoreEnvironmentFlag = 0 ;
1159- _testembed_Py_Initialize ();
1182+ _testembed_Py_InitializeFromConfig ();
11601183 result = 0 ;
11611184
11621185 PyObject * r = PyFile_OpenCode ("$$test-filename" );
@@ -1220,7 +1243,7 @@ static int _test_audit(Py_ssize_t setValue)
12201243
12211244 Py_IgnoreEnvironmentFlag = 0 ;
12221245 PySys_AddAuditHook (_audit_hook , & sawSet );
1223- _testembed_Py_Initialize ();
1246+ _testembed_Py_InitializeFromConfig ();
12241247
12251248 if (PySys_Audit ("_testembed.raise" , NULL ) == 0 ) {
12261249 printf ("No error raised" );
@@ -1276,7 +1299,7 @@ static int test_audit_subinterpreter(void)
12761299{
12771300 Py_IgnoreEnvironmentFlag = 0 ;
12781301 PySys_AddAuditHook (_audit_subinterpreter_hook , NULL );
1279- _testembed_Py_Initialize ();
1302+ _testembed_Py_InitializeFromConfig ();
12801303
12811304 Py_NewInterpreter ();
12821305 Py_NewInterpreter ();
@@ -1871,13 +1894,13 @@ static int test_unicode_id_init(void)
18711894 _Py_IDENTIFIER (test_unicode_id_init );
18721895
18731896 // Initialize Python once without using the identifier
1874- _testembed_Py_Initialize ();
1897+ _testembed_Py_InitializeFromConfig ();
18751898 Py_Finalize ();
18761899
18771900 // Now initialize Python multiple times and use the identifier.
18781901 // The first _PyUnicode_FromId() call initializes the identifier index.
18791902 for (int i = 0 ; i < 3 ; i ++ ) {
1880- _testembed_Py_Initialize ();
1903+ _testembed_Py_InitializeFromConfig ();
18811904
18821905 PyObject * str1 , * str2 ;
18831906
@@ -2021,7 +2044,7 @@ unwrap_allocator(PyMemAllocatorEx *allocator)
20212044static int
20222045test_get_incomplete_frame (void )
20232046{
2024- _testembed_Py_Initialize ();
2047+ _testembed_Py_InitializeFromConfig ();
20252048 PyMemAllocatorEx allocator ;
20262049 wrap_allocator (& allocator );
20272050 // Force an allocation with an incomplete (generator) frame:
@@ -2053,6 +2076,7 @@ struct TestCase
20532076static struct TestCase TestCases [] = {
20542077 // Python initialization
20552078 {"test_repeated_init_exec" , test_repeated_init_exec },
2079+ {"test_repeated_simple_init" , test_repeated_simple_init },
20562080 {"test_forced_io_encoding" , test_forced_io_encoding },
20572081 {"test_repeated_init_and_subinterpreters" , test_repeated_init_and_subinterpreters },
20582082 {"test_repeated_init_and_inittab" , test_repeated_init_and_inittab },
0 commit comments