# HG changeset patch # User Alain Leufroy # Date 1400681657 -7200 # Node ID 93a44cf0d030d932aa81e45cc8c6c7d66b600306 # Parent f288ab643958e3d8a924a035ee474de6b4aa1f79 [cwvreg] cleanup the event manager when reloading modules Closes #3848995 The event manager callbacks are not cleaned during reloading. So the callback defined in the reloaded module appears twice (old and new version). This may cause problem when the old version is called. diff -r f288ab643958 -r 93a44cf0d030 __pkginfo__.py --- a/__pkginfo__.py Tue Jul 08 14:02:43 2014 +0200 +++ b/__pkginfo__.py Wed May 21 16:14:17 2014 +0200 @@ -40,7 +40,7 @@ ] __depends__ = { - 'logilab-common': '>= 0.59.0', + 'logilab-common': '>= 0.62.0', 'logilab-mtconverter': '>= 0.8.0', 'rql': '>= 0.31.2', 'yams': '>= 0.38.1', diff -r f288ab643958 -r 93a44cf0d030 cubicweb.spec --- a/cubicweb.spec Tue Jul 08 14:02:43 2014 +0200 +++ b/cubicweb.spec Wed May 21 16:14:17 2014 +0200 @@ -20,7 +20,7 @@ BuildArch: noarch Requires: %{python} -Requires: %{python}-logilab-common >= 0.59.0 +Requires: %{python}-logilab-common >= 0.62.0 Requires: %{python}-logilab-mtconverter >= 0.8.0 Requires: %{python}-rql >= 0.31.2 Requires: %{python}-yams >= 0.38.1 diff -r f288ab643958 -r 93a44cf0d030 cwvreg.py --- 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') diff -r f288ab643958 -r 93a44cf0d030 debian/control --- a/debian/control Tue Jul 08 14:02:43 2014 +0200 +++ b/debian/control Wed May 21 16:14:17 2014 +0200 @@ -150,7 +150,7 @@ graphviz, gettext, python-logilab-mtconverter (>= 0.8.0), - python-logilab-common (>= 0.59.0), + python-logilab-common (>= 0.62.0), python-yams (>= 0.38.1), python-yams (<< 0.39), python-rql (>= 0.31.2),