Skip to content

Commit 60ebd65

Browse files
committed
gh-105927: PyImport_AddModule() uses _PyWeakref_GET_REF()
It now raises an exception if sys.modules doesn't hold a strong reference to the module. Elaborate the comment explaining why a weak reference is used to create a borrowed reference.
1 parent 193a2b2 commit 60ebd65

File tree

1 file changed

+18
-3
lines changed

1 file changed

+18
-3
lines changed

Python/import.c

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -373,15 +373,30 @@ PyImport_AddModuleObject(PyObject *name)
373373
return NULL;
374374
}
375375

376-
// gh-86160: PyImport_AddModuleObject() returns a borrowed reference
376+
// gh-86160: PyImport_AddModuleObject() returns a borrowed reference.
377+
// Create a weak reference to produce a borrowed reference, since it can
378+
// become NULL. sys.modules type can be different than dict and it is not
379+
// guaranteed that it keeps a strong reference to the module. It can be a
380+
// custom mapping with __getitem__() which returns a new object or removes
381+
// returned object, or __setitem__ which does nothing. There is so much
382+
// unknown. With weakref we can be sure that we get either a reference to
383+
// live object or NULL.
384+
//
385+
// Use PyImport_AddModuleRef() to avoid these issues.
377386
PyObject *ref = PyWeakref_NewRef(mod, NULL);
378387
Py_DECREF(mod);
379388
if (ref == NULL) {
380389
return NULL;
381390
}
382-
383-
mod = PyWeakref_GetObject(ref);
391+
mod = _PyWeakref_GET_REF(ref);
384392
Py_DECREF(ref);
393+
Py_XDECREF(mod);
394+
395+
if (mod == NULL && !PyErr_Occurred()) {
396+
PyErr_SetString(PyExc_RuntimeError,
397+
"sys.modules does not hold a strong reference "
398+
"to the module");
399+
}
385400
return mod; /* borrowed reference */
386401
}
387402

0 commit comments

Comments
 (0)