summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVictor Stinner <vstinner@python.org>2021-06-23 14:13:27 +0200
committerGitHub <noreply@github.com>2021-06-23 14:13:27 +0200
commit489699ca05bed5cfd10e847d8580840812b476cd (patch)
treef58b7493648a430be755b5bc5a788923c8774e62 /Programs
parentbpo-42064: Remove stale extern declarations in `sqlite3` headers (GH-26840) (diff)
downloadcpython-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.c58
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}
};