--- a/cwvreg.py Tue Jul 08 14:02:43 2014 +0200
+++ b/cwvreg.py Wed May 21 16:14:17 2014 +0200
@@ -1,4 +1,4 @@
-# copyright 2003-2012 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+# copyright 2003-2014 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
#
# This file is part of CubicWeb.
@@ -609,11 +609,33 @@
if self.is_reload_needed(path):
self.reload(path)
+ def _cleanup_sys_modules(self, path):
+ """Remove submodules of `directories` from `sys.modules` and cleanup
+ CW_EVENT_MANAGER accordingly.
+
+ We take care to properly remove obsolete registry callbacks.
+
+ """
+ caches = {}
+ callbackdata = CW_EVENT_MANAGER.callbacks.values()
+ for callbacklist in callbackdata:
+ for callback in callbacklist:
+ func = callback[0]
+ # for non-function callable, we do nothing interesting
+ module = getattr(func, '__module__', None)
+ caches[id(callback)] = module
+ deleted_modules = set(cleanup_sys_modules(path))
+ for callbacklist in callbackdata:
+ for callback in callbacklist[:]:
+ module = caches[id(callback)]
+ if module and module in deleted_modules:
+ callbacklist.remove(callback)
+
def reload(self, path, force_reload=True):
"""modification detected, reset and reload the vreg"""
CW_EVENT_MANAGER.emit('before-registry-reload')
if force_reload:
- cleanup_sys_modules(path)
+ self._cleanup_sys_modules(path)
cubes = self.config.cubes()
# if the fs code use some cubes not yet registered into the instance
# we should cleanup sys.modules for those as well to avoid potential
@@ -622,7 +644,7 @@
for cube in cfg.expand_cubes(cubes, with_recommends=True):
if not cube in cubes:
cpath = cfg.build_appobjects_cube_path([cfg.cube_dir(cube)])
- cleanup_sys_modules(cpath)
+ self._cleanup_sys_modules(cpath)
self.register_objects(path)
CW_EVENT_MANAGER.emit('after-registry-reload')