diff --git a/Doc/data/python3.12.abi b/Doc/data/python3.12.abi
index ab5190f6966c02..93dc9dbc71174a 100644
--- a/Doc/data/python3.12.abi
+++ b/Doc/data/python3.12.abi
@@ -1710,7 +1710,7 @@
-
+
@@ -2072,7 +2072,7 @@
-
+
@@ -2524,7 +2524,7 @@
-
+
@@ -2548,39 +2548,39 @@
-
+
-
+
-
+
-
+
-
-
+
+
-
-
+
+
-
-
-
+
+
+
-
-
-
+
+
+
-
-
-
+
+
+
@@ -3679,7 +3679,7 @@
-
+
@@ -3698,7 +3698,7 @@
-
+
@@ -3724,65 +3724,68 @@
-
-
+
+
-
+
-
-
-
-
+
+
+
+
-
+
-
-
+
-
-
+
+
-
+
+
+
+
+
-
-
+
+
-
+
-
+
-
-
+
+
-
-
-
-
+
+
+
+
-
-
-
+
+
+
-
-
+
+
-
-
+
+
@@ -3896,22 +3899,22 @@
-
-
-
+
+
+
-
-
+
+
-
-
+
+
-
-
-
+
+
+
@@ -4033,7 +4036,7 @@
-
+
@@ -4089,22 +4092,22 @@
-
+
-
+
-
+
-
+
@@ -4750,7 +4753,7 @@
-
+
@@ -4908,27 +4911,27 @@
-
+
-
+
-
+
-
+
-
+
@@ -5189,7 +5192,7 @@
-
+
@@ -5374,7 +5377,7 @@
-
+
@@ -5411,12 +5414,12 @@
-
+
-
+
@@ -5640,7 +5643,7 @@
-
+
@@ -5672,21 +5675,21 @@
-
+
-
+
-
+
-
+
@@ -5820,12 +5823,12 @@
-
+
-
+
@@ -6136,7 +6139,7 @@
-
+
@@ -6169,11 +6172,11 @@
-
+
-
+
@@ -6590,11 +6593,11 @@
-
+
-
+
@@ -6875,9 +6878,9 @@
-
-
-
+
+
+
@@ -7125,41 +7128,41 @@
-
-
+
+
-
-
-
-
+
+
+
+
-
-
-
-
+
+
+
+
-
-
-
-
+
+
+
+
-
-
-
+
+
+
-
-
-
+
+
+
-
-
-
+
+
+
@@ -7305,9 +7308,9 @@
-
-
-
+
+
+
@@ -7414,7 +7417,7 @@
-
+
@@ -7460,7 +7463,7 @@
-
+
@@ -7484,23 +7487,27 @@
-
+
-
+
-
+
-
+
+
+
+
+
-
+
@@ -7537,30 +7544,30 @@
-
-
+
+
-
-
-
-
+
+
+
+
-
-
+
+
-
-
-
-
+
+
+
+
-
-
-
-
+
+
+
+
@@ -7582,15 +7589,15 @@
-
+
-
+
-
+
@@ -7648,15 +7655,15 @@
-
+
-
+
-
+
@@ -7717,7 +7724,7 @@
-
+
@@ -7807,42 +7814,42 @@
-
-
-
-
-
+
+
+
+
+
-
-
-
+
+
+
-
-
-
+
+
+
-
-
-
+
+
+
-
-
-
+
+
+
-
+
-
-
+
+
-
-
+
+
@@ -7925,33 +7932,33 @@
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
@@ -7993,7 +8000,7 @@
-
+
@@ -8154,7 +8161,7 @@
-
+
@@ -8217,12 +8224,18 @@
+
+
+
+
+
+
-
-
+
+
@@ -8426,13 +8439,13 @@
-
+
-
+
-
+
@@ -8616,21 +8629,21 @@
-
-
+
+
-
-
+
+
-
-
-
+
+
+
-
-
+
+
@@ -8663,40 +8676,40 @@
-
+
-
+
-
+
-
-
+
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
@@ -8837,16 +8850,16 @@
-
+
-
-
-
+
+
+
@@ -9062,7 +9075,7 @@
-
+
@@ -9663,50 +9676,50 @@
-
-
-
+
+
+
-
-
-
+
+
+
-
-
-
-
+
+
+
+
-
-
-
+
+
+
-
-
-
-
-
+
+
+
+
+
-
-
-
-
+
+
+
+
-
-
-
+
+
+
-
-
+
+
-
+
@@ -10841,7 +10854,7 @@
-
+
@@ -10912,10 +10925,10 @@
-
+
-
+
@@ -11147,7 +11160,7 @@
-
+
@@ -11420,7 +11433,7 @@
-
+
@@ -11428,8 +11441,8 @@
-
-
+
+
@@ -11948,7 +11961,7 @@
-
+
@@ -11974,28 +11987,28 @@
-
-
-
-
-
+
+
+
+
+
-
+
-
+
-
+
-
+
-
+
-
+
@@ -12064,10 +12077,10 @@
-
+
-
+
@@ -13232,42 +13245,42 @@
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
@@ -13392,12 +13405,12 @@
-
+
-
+
@@ -13410,19 +13423,19 @@
-
+
-
+
-
+
-
+
-
+
@@ -13474,7 +13487,7 @@
-
+
@@ -13488,18 +13501,18 @@
-
+
-
+
-
-
+
+
-
-
+
+
@@ -13528,7 +13541,7 @@
-
+
@@ -13543,7 +13556,7 @@
-
+
@@ -13564,13 +13577,13 @@
-
+
-
+
-
+
@@ -13606,7 +13619,7 @@
-
+
@@ -13678,7 +13691,7 @@
-
+
@@ -13707,7 +13720,7 @@
-
+
@@ -14307,7 +14320,7 @@
-
+
@@ -14367,7 +14380,7 @@
-
+
@@ -14421,7 +14434,7 @@
-
+
@@ -14580,7 +14593,7 @@
-
+
@@ -14664,7 +14677,7 @@
-
+
@@ -15147,7 +15160,7 @@
-
+
@@ -15282,7 +15295,7 @@
-
+
@@ -15366,7 +15379,7 @@
-
+
@@ -15438,7 +15451,7 @@
-
+
@@ -15534,223 +15547,226 @@
-
+
-
+
-
-
+
+
-
-
+
+
-
+
-
-
+
+
-
+
-
+
-
+
-
+
-
+
-
+
-
-
+
+
-
-
+
+
-
-
+
+
-
+
-
-
+
+
-
+
-
+
-
-
+
+
-
+
-
+
-
+
-
-
+
+
-
+
-
-
+
+
-
-
+
+
-
-
+
+
-
+
-
+
-
-
+
+
-
+
-
+
-
-
+
+
-
+
-
+
-
+
-
-
+
+
-
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
+
-
-
+
+
-
+
-
+
-
+
-
-
+
+
-
+
-
+
-
+
-
+
-
-
+
+
-
+
-
-
+
+
-
+
-
+
-
+
-
+
-
-
+
+
-
-
+
+
-
+
-
+
-
+
-
+
-
+
-
-
+
+
-
-
+
+
-
+
-
-
+
+
-
+
-
+
+
+
+
@@ -15873,20 +15889,20 @@
-
+
-
+
-
+
-
+
-
+
-
+
@@ -16043,7 +16059,7 @@
-
+
@@ -16054,7 +16070,7 @@
-
+
@@ -16497,7 +16513,7 @@
-
+
@@ -16613,7 +16629,7 @@
-
+
@@ -16722,16 +16738,16 @@
-
+
-
+
-
+
-
+
@@ -17056,7 +17072,7 @@
-
+
@@ -17802,13 +17818,13 @@
-
+
-
+
@@ -18653,76 +18669,76 @@
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
@@ -18731,86 +18747,86 @@
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
@@ -18819,11 +18835,11 @@
-
+
-
+
@@ -18837,40 +18853,40 @@
-
+
-
+
-
+
-
+
-
+
-
+
-
+
@@ -18881,22 +18897,22 @@
-
+
-
+
-
+
-
+
@@ -18906,39 +18922,39 @@
-
+
-
+
-
+
-
+
-
+
-
+
-
+
@@ -18949,31 +18965,31 @@
-
+
-
+
-
+
-
+
-
+
-
+
@@ -19016,7 +19032,7 @@
-
+
@@ -19028,7 +19044,7 @@
-
+
@@ -20032,41 +20048,41 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
@@ -20762,25 +20778,25 @@
-
+
-
+
-
+
-
+
@@ -20879,19 +20895,19 @@
-
+
-
+
-
+
-
+
@@ -20899,7 +20915,7 @@
-
+
@@ -20910,12 +20926,12 @@
-
+
-
+
@@ -21077,7 +21093,7 @@
-
+
@@ -21267,7 +21283,7 @@
-
+
@@ -21360,7 +21376,7 @@
-
+
@@ -21376,6 +21392,11 @@
+
+
+
+
+
@@ -21673,11 +21694,11 @@
-
+
-
+
@@ -21704,11 +21725,11 @@
-
+
-
+
@@ -21789,7 +21810,7 @@
-
+
@@ -21814,21 +21835,21 @@
-
+
-
+
-
+
-
+
@@ -21944,7 +21965,7 @@
-
+
@@ -22010,30 +22031,30 @@
-
-
+
+
-
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
+
@@ -22072,7 +22093,7 @@
-
+
@@ -22301,8 +22322,8 @@
-
-
+
+
@@ -22460,11 +22481,11 @@
-
+
-
+
@@ -22816,41 +22837,41 @@
-
-
-
-
+
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+
-
-
-
-
+
+
+
+
-
+
-
-
-
-
+
+
+
+
-
-
-
-
-
+
+
+
+
+
@@ -22964,7 +22985,7 @@
-
+
@@ -23357,12 +23378,12 @@
-
-
+
+
-
-
+
+
@@ -23431,43 +23452,43 @@
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
@@ -23544,107 +23565,123 @@
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
+
+
+
-
-
-
-
+
+
+
+
-
-
-
-
+
+
+
+
-
-
-
-
+
+
+
+
-
-
-
-
+
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+
-
-
-
-
+
+
+
+
-
-
-
-
+
+
+
+
-
-
-
-
-
+
+
+
+
+
-
-
-
-
-
+
+
+
+
+
-
-
-
-
-
+
+
+
+
+
-
-
-
-
-
+
+
+
+
+
-
-
-
+
+
+
@@ -24103,6 +24140,10 @@
+
+
+
+
@@ -24134,121 +24175,121 @@
-
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
-
+
+
+
-
-
-
-
+
+
+
+
-
-
-
+
+
+
-
-
-
+
+
+
-
-
+
+
-
-
-
+
+
+
-
+
-
+
-
-
-
+
+
+
-
-
+
+
-
-
+
+
-
-
-
-
+
+
+
+
-
-
-
-
+
+
+
+
-
-
+
+
-
-
-
+
+
+
-
-
-
-
+
+
+
+
-
-
-
-
-
+
+
+
+
+
-
-
+
+
-
+
@@ -24275,7 +24316,7 @@
-
+
@@ -24581,7 +24622,7 @@
-
+
@@ -24759,21 +24800,21 @@
-
+
-
+
-
+
-
+
-
+
-
+
@@ -24809,21 +24850,24 @@
-
+
+
+
+
-
+
-
+
-
+
@@ -25259,7 +25303,7 @@
-
+
@@ -25273,18 +25317,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
@@ -25307,9 +25339,6 @@
-
-
-
@@ -25461,7 +25490,7 @@
-
+
@@ -25481,16 +25510,16 @@
-
+
-
+
-
+
@@ -25558,10 +25587,6 @@
-
-
-
-
@@ -25818,128 +25843,128 @@
-
-
-
-
-
+
+
+
+
+
-
-
-
-
+
+
+
+
-
-
-
+
+
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+
-
-
-
+
+
+
-
-
-
-
+
+
+
+
-
-
-
-
+
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
-
-
-
+
+
+
-
-
-
-
+
+
+
+
-
-
-
-
-
+
+
+
+
+
-
-
+
+
-
-
-
-
+
+
+
+
-
-
-
-
-
+
+
+
+
+
-
-
-
+
+
+
-
-
-
+
+
+
@@ -26220,12 +26245,12 @@
-
+
-
+
@@ -26421,38 +26446,38 @@
-
-
-
+
+
+
-
-
-
-
+
+
+
+
-
+
-
-
+
+
-
-
+
+
-
-
-
+
+
+
-
-
+
+
-
+
@@ -26469,7 +26494,7 @@
-
+
diff --git a/Include/internal/pycore_global_objects_fini_generated.h b/Include/internal/pycore_global_objects_fini_generated.h
index 439f47a263dfa1..909fe90b3f56a0 100644
--- a/Include/internal/pycore_global_objects_fini_generated.h
+++ b/Include/internal/pycore_global_objects_fini_generated.h
@@ -1186,6 +1186,7 @@ _PyStaticObjects_CheckRefcnt(PyInterpreterState *interp) {
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(sound));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(source));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(source_traceback));
+ _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(spam));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(src));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(src_dir_fd));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(stacklevel));
diff --git a/Include/internal/pycore_global_strings.h b/Include/internal/pycore_global_strings.h
index 0c84999cbf8127..26c1be3b2aa993 100644
--- a/Include/internal/pycore_global_strings.h
+++ b/Include/internal/pycore_global_strings.h
@@ -675,6 +675,7 @@ struct _Py_global_strings {
STRUCT_FOR_ID(sound)
STRUCT_FOR_ID(source)
STRUCT_FOR_ID(source_traceback)
+ STRUCT_FOR_ID(spam)
STRUCT_FOR_ID(src)
STRUCT_FOR_ID(src_dir_fd)
STRUCT_FOR_ID(stacklevel)
diff --git a/Include/internal/pycore_runtime_init_generated.h b/Include/internal/pycore_runtime_init_generated.h
index 07f237b2905864..dbfb633c7090e8 100644
--- a/Include/internal/pycore_runtime_init_generated.h
+++ b/Include/internal/pycore_runtime_init_generated.h
@@ -1181,6 +1181,7 @@ extern "C" {
INIT_ID(sound), \
INIT_ID(source), \
INIT_ID(source_traceback), \
+ INIT_ID(spam), \
INIT_ID(src), \
INIT_ID(src_dir_fd), \
INIT_ID(stacklevel), \
diff --git a/Include/internal/pycore_unicodeobject_generated.h b/Include/internal/pycore_unicodeobject_generated.h
index 9b470094b7afe2..9f9e23f5cdeb69 100644
--- a/Include/internal/pycore_unicodeobject_generated.h
+++ b/Include/internal/pycore_unicodeobject_generated.h
@@ -1866,6 +1866,9 @@ _PyUnicode_InitStaticStrings(PyInterpreterState *interp) {
string = &_Py_ID(source_traceback);
assert(_PyUnicode_CheckConsistency(string, 1));
_PyUnicode_InternInPlace(interp, &string);
+ string = &_Py_ID(spam);
+ assert(_PyUnicode_CheckConsistency(string, 1));
+ _PyUnicode_InternInPlace(interp, &string);
string = &_Py_ID(src);
assert(_PyUnicode_CheckConsistency(string, 1));
_PyUnicode_InternInPlace(interp, &string);
diff --git a/Lib/test/test_capi/test_getargs.py b/Lib/test/test_capi/test_getargs.py
index 3d8768b8845f8d..69bd0f4c5f197c 100644
--- a/Lib/test/test_capi/test_getargs.py
+++ b/Lib/test/test_capi/test_getargs.py
@@ -4,11 +4,17 @@
import sys
from test import support
from test.support import import_helper
+from test.support import script_helper
from test.support import warnings_helper
# Skip this test if the _testcapi module isn't available.
_testcapi = import_helper.import_module('_testcapi')
from _testcapi import getargs_keywords, getargs_keyword_only
+try:
+ import _testinternalcapi
+except ImportError:
+ _testinternalcapi = NULL
+
# > How about the following counterproposal. This also changes some of
# > the other format codes to be a little more regular.
# >
@@ -1369,6 +1375,33 @@ def test_nested_tuple(self):
"argument 1 must be sequence of length 1, not 0"):
parse(((),), {}, '(' + f + ')', ['a'])
+ @unittest.skipIf(_testinternalcapi is None, 'needs _testinternalcapi')
+ def test_gh_119213(self):
+ rc, out, err = script_helper.assert_python_ok("-c", """if True:
+ from test import support
+ script = '''if True:
+ import _testinternalcapi
+ _testinternalcapi.gh_119213_getargs(spam='eggs')
+ '''
+ config = dict(
+ allow_fork=False,
+ allow_exec=False,
+ allow_threads=True,
+ allow_daemon_threads=False,
+ use_main_obmalloc=False,
+ gil=2,
+ check_multi_interp_extensions=True,
+ )
+ rc = support.run_in_subinterp_with_config(script, **config)
+ assert rc == 0
+
+ # The crash is different if the interpreter was not destroyed first.
+ #interpid = _testinternalcapi.create_interpreter()
+ #rc = _testinternalcapi.exec_interpreter(interpid, script)
+ #assert rc == 0
+ """)
+ self.assertEqual(rc, 0)
+
if __name__ == "__main__":
unittest.main()
diff --git a/Misc/NEWS.d/next/Core and Builtins/2024-05-21-11-27-14.gh-issue-119213.nxjxrt.rst b/Misc/NEWS.d/next/Core and Builtins/2024-05-21-11-27-14.gh-issue-119213.nxjxrt.rst
new file mode 100644
index 00000000000000..e9073b4ba08798
--- /dev/null
+++ b/Misc/NEWS.d/next/Core and Builtins/2024-05-21-11-27-14.gh-issue-119213.nxjxrt.rst
@@ -0,0 +1,3 @@
+Non-builtin modules built with argument clinic were crashing if used in a
+subinterpreter before the main interpreter. The objects that were causing
+the problem by leaking between interpreters carelessly have been fixed.
diff --git a/Modules/_testinternalcapi.c b/Modules/_testinternalcapi.c
index 22d156725f545c..c758420c3deab4 100644
--- a/Modules/_testinternalcapi.c
+++ b/Modules/_testinternalcapi.c
@@ -1055,6 +1055,24 @@ pending_identify(PyObject *self, PyObject *args)
}
+/*[clinic input]
+gh_119213_getargs
+
+ spam: object = None
+
+Test _PyArg_Parser.kwtuple
+[clinic start generated code]*/
+
+static PyObject *
+gh_119213_getargs_impl(PyObject *module, PyObject *spam)
+/*[clinic end generated code: output=d8d9c95d5b446802 input=65ef47511da80fc2]*/
+{
+ // It must never have been called in the main interprer
+ assert(!_Py_IsMainInterpreter(PyInterpreterState_Get()));
+ return Py_NewRef(spam);
+}
+
+
static PyMethodDef module_functions[] = {
{"get_configs", get_configs, METH_NOARGS},
{"get_recursion_depth", get_recursion_depth, METH_NOARGS},
@@ -1087,6 +1105,7 @@ static PyMethodDef module_functions[] = {
{"pending_threadfunc", _PyCFunction_CAST(pending_threadfunc),
METH_VARARGS | METH_KEYWORDS},
{"pending_identify", pending_identify, METH_VARARGS, NULL},
+ GH_119213_GETARGS_METHODDEF
{NULL, NULL} /* sentinel */
};
diff --git a/Modules/clinic/_testinternalcapi.c.h b/Modules/clinic/_testinternalcapi.c.h
index f5124125874503..1cc4ad4c16c2bb 100644
--- a/Modules/clinic/_testinternalcapi.c.h
+++ b/Modules/clinic/_testinternalcapi.c.h
@@ -206,4 +206,64 @@ _testinternalcapi_assemble_code_object(PyObject *module, PyObject *const *args,
exit:
return return_value;
}
-/*[clinic end generated code: output=2965f1578b986218 input=a9049054013a1b77]*/
+
+PyDoc_STRVAR(gh_119213_getargs__doc__,
+"gh_119213_getargs($module, /, spam=None)\n"
+"--\n"
+"\n"
+"Test _PyArg_Parser.kwtuple");
+
+#define GH_119213_GETARGS_METHODDEF \
+ {"gh_119213_getargs", _PyCFunction_CAST(gh_119213_getargs), METH_FASTCALL|METH_KEYWORDS, gh_119213_getargs__doc__},
+
+static PyObject *
+gh_119213_getargs_impl(PyObject *module, PyObject *spam);
+
+static PyObject *
+gh_119213_getargs(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
+{
+ PyObject *return_value = NULL;
+ #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
+
+ #define NUM_KEYWORDS 1
+ static struct {
+ PyGC_Head _this_is_not_used;
+ PyObject_VAR_HEAD
+ PyObject *ob_item[NUM_KEYWORDS];
+ } _kwtuple = {
+ .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS)
+ .ob_item = { &_Py_ID(spam), },
+ };
+ #undef NUM_KEYWORDS
+ #define KWTUPLE (&_kwtuple.ob_base.ob_base)
+
+ #else // !Py_BUILD_CORE
+ # define KWTUPLE NULL
+ #endif // !Py_BUILD_CORE
+
+ static const char * const _keywords[] = {"spam", NULL};
+ static _PyArg_Parser _parser = {
+ .keywords = _keywords,
+ .fname = "gh_119213_getargs",
+ .kwtuple = KWTUPLE,
+ };
+ #undef KWTUPLE
+ PyObject *argsbuf[1];
+ Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0;
+ PyObject *spam = Py_None;
+
+ args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf);
+ if (!args) {
+ goto exit;
+ }
+ if (!noptargs) {
+ goto skip_optional_pos;
+ }
+ spam = args[0];
+skip_optional_pos:
+ return_value = gh_119213_getargs_impl(module, spam);
+
+exit:
+ return return_value;
+}
+/*[clinic end generated code: output=1fa5cb831dbb391f input=a9049054013a1b77]*/
diff --git a/Python/getargs.c b/Python/getargs.c
index 5e731cdc23cb5f..02bddf0618e578 100644
--- a/Python/getargs.c
+++ b/Python/getargs.c
@@ -4,6 +4,7 @@
#include "Python.h"
#include "pycore_tuple.h" // _PyTuple_ITEMS()
#include "pycore_pylifecycle.h" // _PyArg_Fini
+#include "pycore_pystate.h" // _Py_IsMainInterpreter()
#include
#include
@@ -2002,7 +2003,23 @@ _parser_init(struct _PyArg_Parser *parser)
int owned;
PyObject *kwtuple = parser->kwtuple;
if (kwtuple == NULL) {
+ /* We may temporarily switch to the main interpreter to avoid
+ * creating a tuple that could outlive its owning interpreter. */
+ PyThreadState *save_tstate = NULL;
+ PyThreadState *temp_tstate = NULL;
+ if (!_Py_IsMainInterpreter(PyInterpreterState_Get())) {
+ temp_tstate = PyThreadState_New(_PyInterpreterState_Main());
+ if (temp_tstate == NULL) {
+ return -1;
+ }
+ save_tstate = PyThreadState_Swap(temp_tstate);
+ }
kwtuple = new_kwtuple(keywords, len, pos);
+ if (temp_tstate != NULL) {
+ PyThreadState_Clear(temp_tstate);
+ (void)PyThreadState_Swap(save_tstate);
+ PyThreadState_Delete(temp_tstate);
+ }
if (kwtuple == NULL) {
return 0;
}