2222/* Use path starting with "./" avoids a search along the PATH */
2323#define PROGRAM_NAME L"./_testembed"
2424
25+ #define INIT_LOOPS 16
26+
27+
2528static void _testembed_Py_Initialize (void )
2629{
2730 Py_SetProgramName (PROGRAM_NAME );
@@ -54,9 +57,8 @@ static int test_repeated_init_and_subinterpreters(void)
5457{
5558 PyThreadState * mainstate , * substate ;
5659 PyGILState_STATE gilstate ;
57- int i , j ;
5860
59- for (i = 0 ; i < 15 ; i ++ ) {
61+ for (int i = 1 ; i <= INIT_LOOPS ; i ++ ) {
6062 printf ("--- Pass %d ---\n" , i );
6163 _testembed_Py_Initialize ();
6264 mainstate = PyThreadState_Get ();
@@ -67,7 +69,7 @@ static int test_repeated_init_and_subinterpreters(void)
6769 print_subinterp ();
6870 PyThreadState_Swap (NULL );
6971
70- for (j = 0 ; j < 3 ; j ++ ) {
72+ for (int j = 0 ; j < 3 ; j ++ ) {
7173 substate = Py_NewInterpreter ();
7274 print_subinterp ();
7375 Py_EndInterpreter (substate );
@@ -83,6 +85,20 @@ static int test_repeated_init_and_subinterpreters(void)
8385 return 0 ;
8486}
8587
88+ #define EMBEDDED_EXT_NAME "embedded_ext"
89+
90+ static PyModuleDef embedded_ext = {
91+ PyModuleDef_HEAD_INIT ,
92+ .m_name = EMBEDDED_EXT_NAME ,
93+ .m_size = 0 ,
94+ };
95+
96+ static PyObject *
97+ PyInit_embedded_ext (void )
98+ {
99+ return PyModule_Create (& embedded_ext );
100+ }
101+
86102/*****************************************************
87103 * Test forcing a particular IO encoding
88104 *****************************************************/
@@ -1735,6 +1751,38 @@ static int list_frozen(void)
17351751}
17361752
17371753
1754+ static int test_repeated_init_and_inittab (void )
1755+ {
1756+ // bpo-44441: Py_RunMain() must reset PyImport_Inittab at exit.
1757+ // It must be possible to call PyImport_AppendInittab() or
1758+ // PyImport_ExtendInittab() before each Python initialization.
1759+ for (int i = 1 ; i <= INIT_LOOPS ; i ++ ) {
1760+ printf ("--- Pass %d ---\n" , i );
1761+
1762+ // Call PyImport_AppendInittab() at each iteration
1763+ if (PyImport_AppendInittab (EMBEDDED_EXT_NAME ,
1764+ & PyInit_embedded_ext ) != 0 ) {
1765+ fprintf (stderr , "PyImport_AppendInittab() failed\n" );
1766+ return 1 ;
1767+ }
1768+
1769+ // Initialize Python
1770+ wchar_t * argv [] = {PROGRAM_NAME , L"-c" , L"pass" };
1771+ PyConfig config ;
1772+ PyConfig_InitPythonConfig (& config );
1773+ config .isolated = 1 ;
1774+ config_set_argv (& config , Py_ARRAY_LENGTH (argv ), argv );
1775+ init_from_config_clear (& config );
1776+
1777+ // Py_RunMain() calls _PyImport_Fini2() which resets PyImport_Inittab
1778+ int exitcode = Py_RunMain ();
1779+ if (exitcode != 0 ) {
1780+ return exitcode ;
1781+ }
1782+ }
1783+ return 0 ;
1784+ }
1785+
17381786
17391787/* *********************************************************
17401788 * List of test cases and the function that implements it.
@@ -1755,8 +1803,10 @@ struct TestCase
17551803};
17561804
17571805static struct TestCase TestCases [] = {
1806+ // Python initialization
17581807 {"test_forced_io_encoding" , test_forced_io_encoding },
17591808 {"test_repeated_init_and_subinterpreters" , test_repeated_init_and_subinterpreters },
1809+ {"test_repeated_init_and_inittab" , test_repeated_init_and_inittab },
17601810 {"test_pre_initialization_api" , test_pre_initialization_api },
17611811 {"test_pre_initialization_sys_options" , test_pre_initialization_sys_options },
17621812 {"test_bpo20891" , test_bpo20891 },
@@ -1796,6 +1846,7 @@ static struct TestCase TestCases[] = {
17961846 {"test_run_main" , test_run_main },
17971847 {"test_get_argc_argv" , test_get_argc_argv },
17981848
1849+ // Audit
17991850 {"test_open_code_hook" , test_open_code_hook },
18001851 {"test_audit" , test_audit },
18011852 {"test_audit_subinterpreter" , test_audit_subinterpreter },
@@ -1805,8 +1856,10 @@ static struct TestCase TestCases[] = {
18051856 {"test_audit_run_startup" , test_audit_run_startup },
18061857 {"test_audit_run_stdin" , test_audit_run_stdin },
18071858
1859+ // Specific C API
18081860 {"test_unicode_id_init" , test_unicode_id_init },
18091861
1862+ // Command
18101863 {"list_frozen" , list_frozen },
18111864 {NULL , NULL }
18121865};
0 commit comments