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.
This commit is contained in:
@@ -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}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user