|
12 | 12 | #include"pycore_pymem.h"// _PyMem_SetDefaultAllocator()
|
13 | 13 | #include"pycore_pystate.h"// _PyInterpreterState_GET()
|
14 | 14 | #include"pycore_sysmodule.h"// _PySys_Audit()
|
| 15 | +#include"pycore_weakref.h"// _PyWeakref_GET_REF() |
15 | 16 | #include"marshal.h"// PyMarshal_ReadObjectFromString()
|
16 | 17 | #include"importdl.h"// _PyImport_DynLoadFiletab
|
17 | 18 | #include"pydtrace.h"// PyDTrace_IMPORT_FIND_LOAD_START_ENABLED()
|
@@ -373,15 +374,30 @@ PyImport_AddModuleObject(PyObject *name)
|
373 | 374 | returnNULL;
|
374 | 375 | }
|
375 | 376 |
|
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. |
377 | 387 | PyObject*ref=PyWeakref_NewRef(mod,NULL);
|
378 | 388 | Py_DECREF(mod);
|
379 | 389 | if (ref==NULL) {
|
380 | 390 | returnNULL;
|
381 | 391 | }
|
382 |
| - |
383 |
| -mod=PyWeakref_GetObject(ref); |
| 392 | +mod=_PyWeakref_GET_REF(ref); |
384 | 393 | 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 | + } |
385 | 401 | returnmod;/* borrowed reference */
|
386 | 402 | }
|
387 | 403 |
|
|