@@ -340,6 +340,25 @@ imp_release_lock(PyObject *self, PyObject *noargs)
340340 return Py_None ;
341341}
342342
343+ PyObject *
344+ PyImport_GetModulesReloading (void )
345+ {
346+ PyInterpreterState * interp = PyThreadState_Get ()-> interp ;
347+ if (interp -> modules_reloading == NULL )
348+ Py_FatalError ("PyImport_GetModuleDict: no modules_reloading dictionary!" );
349+ return interp -> modules_reloading ;
350+ }
351+
352+ static void
353+ imp_modules_reloading_clear (void )
354+ {
355+ PyInterpreterState * interp = PyThreadState_Get ()-> interp ;
356+ if (interp -> modules_reloading == NULL )
357+ return ;
358+ PyDict_Clear (interp -> modules_reloading );
359+ return ;
360+ }
361+
343362/* Helper for sys */
344363
345364PyObject *
@@ -499,6 +518,7 @@ PyImport_Cleanup(void)
499518 PyDict_Clear (modules );
500519 interp -> modules = NULL ;
501520 Py_DECREF (modules );
521+ Py_CLEAR (interp -> modules_reloading );
502522}
503523
504524
@@ -2401,8 +2421,9 @@ import_submodule(PyObject *mod, char *subname, char *fullname)
24012421PyObject *
24022422PyImport_ReloadModule (PyObject * m )
24032423{
2424+ PyObject * modules_reloading = PyImport_GetModulesReloading ();
24042425 PyObject * modules = PyImport_GetModuleDict ();
2405- PyObject * path = NULL , * loader = NULL ;
2426+ PyObject * path = NULL , * loader = NULL , * existing_m = NULL ;
24062427 char * name , * subname ;
24072428 char buf [MAXPATHLEN + 1 ];
24082429 struct filedescr * fdp ;
@@ -2423,20 +2444,30 @@ PyImport_ReloadModule(PyObject *m)
24232444 name );
24242445 return NULL ;
24252446 }
2447+ if ((existing_m = PyDict_GetItemString (modules_reloading , name )) != NULL ) {
2448+ /* Due to a recursive reload, this module is already being reloaded. */
2449+ Py_INCREF (existing_m );
2450+ return existing_m ;
2451+ }
2452+ PyDict_SetItemString (modules_reloading , name , m );
2453+
24262454 subname = strrchr (name , '.' );
24272455 if (subname == NULL )
24282456 subname = name ;
24292457 else {
24302458 PyObject * parentname , * parent ;
24312459 parentname = PyString_FromStringAndSize (name , (subname - name ));
2432- if (parentname == NULL )
2460+ if (parentname == NULL ) {
2461+ imp_modules_reloading_clear ();
24332462 return NULL ;
2463+ }
24342464 parent = PyDict_GetItem (modules , parentname );
24352465 if (parent == NULL ) {
24362466 PyErr_Format (PyExc_ImportError ,
24372467 "reload(): parent %.200s not in sys.modules" ,
24382468 PyString_AS_STRING (parentname ));
24392469 Py_DECREF (parentname );
2470+ imp_modules_reloading_clear ();
24402471 return NULL ;
24412472 }
24422473 Py_DECREF (parentname );
@@ -2451,6 +2482,7 @@ PyImport_ReloadModule(PyObject *m)
24512482
24522483 if (fdp == NULL ) {
24532484 Py_XDECREF (loader );
2485+ imp_modules_reloading_clear ();
24542486 return NULL ;
24552487 }
24562488
@@ -2467,6 +2499,7 @@ PyImport_ReloadModule(PyObject *m)
24672499 */
24682500 PyDict_SetItemString (modules , name , m );
24692501 }
2502+ imp_modules_reloading_clear ();
24702503 return newm ;
24712504}
24722505
0 commit comments