Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit ee52158

Browse files
authored
gh-105927: PyImport_AddModule() uses _PyWeakref_GET_REF() (#106001)
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 ee52158

File tree

1 file changed

+19
-3
lines changed

1 file changed

+19
-3
lines changed

Python/import.c

+19-3
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include "pycore_pymem.h" // _PyMem_SetDefaultAllocator()
1313
#include "pycore_pystate.h" // _PyInterpreterState_GET()
1414
#include "pycore_sysmodule.h" // _PySys_Audit()
15+
#include "pycore_weakref.h" // _PyWeakref_GET_REF()
1516
#include "marshal.h" // PyMarshal_ReadObjectFromString()
1617
#include "importdl.h" // _PyImport_DynLoadFiletab
1718
#include "pydtrace.h" // PyDTrace_IMPORT_FIND_LOAD_START_ENABLED()
@@ -373,15 +374,30 @@ PyImport_AddModuleObject(PyObject *name)
373374
return NULL;
374375
}
375376

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

0 commit comments

Comments
 (0)