diff options
author | Victor Stinner <vstinner@python.org> | 2021-06-23 14:13:27 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-06-23 14:13:27 +0200 |
commit | 489699ca05bed5cfd10e847d8580840812b476cd (patch) | |
tree | f58b7493648a430be755b5bc5a788923c8774e62 /Programs | |
parent | bpo-42064: Remove stale extern declarations in `sqlite3` headers (GH-26840) (diff) | |
download | cpython-489699ca05bed5cfd10e847d8580840812b476cd.tar.gz cpython-489699ca05bed5cfd10e847d8580840812b476cd.tar.bz2 cpython-489699ca05bed5cfd10e847d8580840812b476cd.zip |
bpo-44441: _PyImport_Fini2() resets PyImport_Inittab (GH-26874)
Py_RunMain() now resets PyImport_Inittab to its initial value at
exit. It must be possible to call PyImport_AppendInittab() or
PyImport_ExtendInittab() at each Python initialization.
Diffstat (limited to 'Programs')
-rw-r--r-- | Programs/_testembed.c | 58 |
1 files changed, 55 insertions, 3 deletions
diff --git a/Programs/_testembed.c b/Programs/_testembed.c index a5ae7c1d863..d963cb3dc7e 100644 --- a/Programs/_testembed.c +++ b/Programs/_testembed.c @@ -22,6 +22,8 @@ /* Use path starting with "./" avoids a search along the PATH */ #define PROGRAM_NAME L"./_testembed" +#define INIT_LOOPS 16 + // Ignore Py_DEPRECATED() compiler warnings: deprecated functions are // tested on purpose here. _Py_COMP_DIAG_PUSH @@ -67,9 +69,8 @@ static int test_repeated_init_and_subinterpreters(void) { PyThreadState *mainstate, *substate; PyGILState_STATE gilstate; - int i, j; - for (i=0; i<15; i++) { + for (int i=1; i <= INIT_LOOPS; i++) { printf("--- Pass %d ---\n", i); _testembed_Py_Initialize(); mainstate = PyThreadState_Get(); @@ -80,7 +81,7 @@ static int test_repeated_init_and_subinterpreters(void) print_subinterp(); PyThreadState_Swap(NULL); - for (j=0; j<3; j++) { + for (int j=0; j<3; j++) { substate = Py_NewInterpreter(); print_subinterp(); Py_EndInterpreter(substate); @@ -96,6 +97,20 @@ static int test_repeated_init_and_subinterpreters(void) return 0; } +#define EMBEDDED_EXT_NAME "embedded_ext" + +static PyModuleDef embedded_ext = { + PyModuleDef_HEAD_INIT, + .m_name = EMBEDDED_EXT_NAME, + .m_size = 0, +}; + +static PyObject* +PyInit_embedded_ext(void) +{ + return PyModule_Create(&embedded_ext); +} + /***************************************************** * Test forcing a particular IO encoding *****************************************************/ @@ -1790,6 +1805,38 @@ static int list_frozen(void) } +static int test_repeated_init_and_inittab(void) +{ + // bpo-44441: Py_RunMain() must reset PyImport_Inittab at exit. + // It must be possible to call PyImport_AppendInittab() or + // PyImport_ExtendInittab() before each Python initialization. + for (int i=1; i <= INIT_LOOPS; i++) { + printf("--- Pass %d ---\n", i); + + // Call PyImport_AppendInittab() at each iteration + if (PyImport_AppendInittab(EMBEDDED_EXT_NAME, + &PyInit_embedded_ext) != 0) { + fprintf(stderr, "PyImport_AppendInittab() failed\n"); + return 1; + } + + // Initialize Python + wchar_t* argv[] = {PROGRAM_NAME, L"-c", L"pass"}; + PyConfig config; + PyConfig_InitPythonConfig(&config); + config.isolated = 1; + config_set_argv(&config, Py_ARRAY_LENGTH(argv), argv); + init_from_config_clear(&config); + + // Py_RunMain() calls _PyImport_Fini2() which resets PyImport_Inittab + int exitcode = Py_RunMain(); + if (exitcode != 0) { + return exitcode; + } + } + return 0; +} + /* ********************************************************* * List of test cases and the function that implements it. @@ -1810,8 +1857,10 @@ struct TestCase }; static struct TestCase TestCases[] = { + // Python initialization {"test_forced_io_encoding", test_forced_io_encoding}, {"test_repeated_init_and_subinterpreters", test_repeated_init_and_subinterpreters}, + {"test_repeated_init_and_inittab", test_repeated_init_and_inittab}, {"test_pre_initialization_api", test_pre_initialization_api}, {"test_pre_initialization_sys_options", test_pre_initialization_sys_options}, {"test_bpo20891", test_bpo20891}, @@ -1851,6 +1900,7 @@ static struct TestCase TestCases[] = { {"test_run_main", test_run_main}, {"test_get_argc_argv", test_get_argc_argv}, + // Audit {"test_open_code_hook", test_open_code_hook}, {"test_audit", test_audit}, {"test_audit_subinterpreter", test_audit_subinterpreter}, @@ -1860,11 +1910,13 @@ static struct TestCase TestCases[] = { {"test_audit_run_startup", test_audit_run_startup}, {"test_audit_run_stdin", test_audit_run_stdin}, + // Specific C API {"test_unicode_id_init", test_unicode_id_init}, #ifndef MS_WINDOWS {"test_frozenmain", test_frozenmain}, #endif + // Command {"list_frozen", list_frozen}, {NULL, NULL} }; |