@@ -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 ;
@@ -765,7 +788,7 @@ static int test_init_compat_env(void)
765788 /* Test initialization from environment variables */
766789 Py_IgnoreEnvironmentFlag = 0 ;
767790 set_all_env_vars ();
768- _testembed_Py_Initialize ();
791+ _testembed_Py_InitializeFromConfig ();
769792 dump_config ();
770793 Py_Finalize ();
771794 return 0 ;
@@ -801,7 +824,7 @@ static int test_init_env_dev_mode(void)
801824 /* Test initialization from environment variables */
802825 Py_IgnoreEnvironmentFlag = 0 ;
803826 set_all_env_vars_dev_mode ();
804- _testembed_Py_Initialize ();
827+ _testembed_Py_InitializeFromConfig ();
805828 dump_config ();
806829 Py_Finalize ();
807830 return 0 ;
@@ -814,7 +837,7 @@ static int test_init_env_dev_mode_alloc(void)
814837 Py_IgnoreEnvironmentFlag = 0 ;
815838 set_all_env_vars_dev_mode ();
816839 putenv ("PYTHONMALLOC=malloc" );
817- _testembed_Py_Initialize ();
840+ _testembed_Py_InitializeFromConfig ();
818841 dump_config ();
819842 Py_Finalize ();
820843 return 0 ;
@@ -1154,7 +1177,7 @@ static int test_open_code_hook(void)
11541177 }
11551178
11561179 Py_IgnoreEnvironmentFlag = 0 ;
1157- _testembed_Py_Initialize ();
1180+ _testembed_Py_InitializeFromConfig ();
11581181 result = 0 ;
11591182
11601183 PyObject * r = PyFile_OpenCode ("$$test-filename" );
@@ -1218,7 +1241,7 @@ static int _test_audit(Py_ssize_t setValue)
12181241
12191242 Py_IgnoreEnvironmentFlag = 0 ;
12201243 PySys_AddAuditHook (_audit_hook , & sawSet );
1221- _testembed_Py_Initialize ();
1244+ _testembed_Py_InitializeFromConfig ();
12221245
12231246 if (PySys_Audit ("_testembed.raise" , NULL ) == 0 ) {
12241247 printf ("No error raised" );
@@ -1274,7 +1297,7 @@ static int test_audit_subinterpreter(void)
12741297{
12751298 Py_IgnoreEnvironmentFlag = 0 ;
12761299 PySys_AddAuditHook (_audit_subinterpreter_hook , NULL );
1277- _testembed_Py_Initialize ();
1300+ _testembed_Py_InitializeFromConfig ();
12781301
12791302 Py_NewInterpreter ();
12801303 Py_NewInterpreter ();
@@ -1869,13 +1892,13 @@ static int test_unicode_id_init(void)
18691892 _Py_IDENTIFIER (test_unicode_id_init );
18701893
18711894 // Initialize Python once without using the identifier
1872- _testembed_Py_Initialize ();
1895+ _testembed_Py_InitializeFromConfig ();
18731896 Py_Finalize ();
18741897
18751898 // Now initialize Python multiple times and use the identifier.
18761899 // The first _PyUnicode_FromId() call initializes the identifier index.
18771900 for (int i = 0 ; i < 3 ; i ++ ) {
1878- _testembed_Py_Initialize ();
1901+ _testembed_Py_InitializeFromConfig ();
18791902
18801903 PyObject * str1 , * str2 ;
18811904
@@ -2007,7 +2030,7 @@ unwrap_allocator(PyMemAllocatorEx *allocator)
20072030static int
20082031test_get_incomplete_frame (void )
20092032{
2010- _testembed_Py_Initialize ();
2033+ _testembed_Py_InitializeFromConfig ();
20112034 PyMemAllocatorEx allocator ;
20122035 wrap_allocator (& allocator );
20132036 // Force an allocation with an incomplete (generator) frame:
@@ -2039,6 +2062,7 @@ struct TestCase
20392062static struct TestCase TestCases [] = {
20402063 // Python initialization
20412064 {"test_repeated_init_exec" , test_repeated_init_exec },
2065+ {"test_repeated_simple_init" , test_repeated_simple_init },
20422066 {"test_forced_io_encoding" , test_forced_io_encoding },
20432067 {"test_repeated_init_and_subinterpreters" , test_repeated_init_and_subinterpreters },
20442068 {"test_repeated_init_and_inittab" , test_repeated_init_and_inittab },
0 commit comments