Skip to content

Commit 9dda902

Browse files
miss-islingtonvstinner
andauthoredNov 21, 2022
gh-99578: Fix refleak in _imp.create_builtin() (GH-99642)
Fix a reference bug in _imp.create_builtin() after the creation of the first sub-interpreter for modules "builtins" and "sys". (cherry picked from commit cb2ef8b) Co-authored-by: Victor Stinner <vstinner@python.org>
1 parent bb4c091 commit 9dda902

File tree

3 files changed

+35
-1
lines changed

3 files changed

+35
-1
lines changed
 

‎Lib/test/test_imp.py

+30
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import gc
12
import importlib
23
import importlib.util
34
import os
@@ -383,6 +384,35 @@ def test_find_and_load_checked_pyc(self):
383384
self.assertEqual(mod.x, 42)
384385

385386

387+
@support.cpython_only
388+
def test_create_builtin_subinterp(self):
389+
# gh-99578: create_builtin() behavior changes after the creation of the
390+
# first sub-interpreter. Test both code paths, before and after the
391+
# creation of a sub-interpreter. Previously, create_builtin() had
392+
# a reference leak after the creation of the first sub-interpreter.
393+
394+
import builtins
395+
create_builtin = support.get_attribute(_imp, "create_builtin")
396+
class Spec:
397+
name = "builtins"
398+
spec = Spec()
399+
400+
def check_get_builtins():
401+
refcnt = sys.getrefcount(builtins)
402+
mod = _imp.create_builtin(spec)
403+
self.assertIs(mod, builtins)
404+
self.assertEqual(sys.getrefcount(builtins), refcnt + 1)
405+
# Check that a GC collection doesn't crash
406+
gc.collect()
407+
408+
check_get_builtins()
409+
410+
ret = support.run_in_subinterp("import builtins")
411+
self.assertEqual(ret, 0)
412+
413+
check_get_builtins()
414+
415+
386416
class ReloadTests(unittest.TestCase):
387417

388418
"""Very basic tests to make sure that imp.reload() operates just like
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Fix a reference bug in :func:`_imp.create_builtin()` after the creation of the
2+
first sub-interpreter for modules ``builtins`` and ``sys``. Patch by Victor
3+
Stinner.

‎Python/import.c

+2-1
Original file line numberDiff line numberDiff line change
@@ -978,7 +978,8 @@ create_builtin(PyThreadState *tstate, PyObject *name, PyObject *spec)
978978
if (_PyUnicode_EqualToASCIIString(name, p->name)) {
979979
if (p->initfunc == NULL) {
980980
/* Cannot re-init internal module ("sys" or "builtins") */
981-
return PyImport_AddModuleObject(name);
981+
mod = PyImport_AddModuleObject(name);
982+
return Py_XNewRef(mod);
982983
}
983984
mod = _PyImport_InitFunc_TrampolineCall(*p->initfunc);
984985
if (mod == NULL) {

0 commit comments

Comments
 (0)