
ra at burningman
Sep 16, 2008, 2:28 PM
Post #2 of 2
(345 views)
Permalink
|
|
Re: back-porting a GenericSetup fix to the 1.4 branch
[In reply to]
|
|
Rob Miller wrote: > hi all, > > currently, on the 1.4 branch of GenericSetup, there is what i consider to be a > bug in the component registry import code. the issue is that when you re-run > the import step, even if you are not in purge mode, then any utilities that > are registered with the given site manager will be replaced with brand new > instances. since local utilities are persistent objects, and often store > important information within themselves, this seems to me a big enough issue > to warrant a bug-fix on the 1.4 branch. > > this appears to have been resolved on the trunk, as part of a bigger set of > component registry improvements. i've backported the changes (with minor > adjustments to account for other version-related differences) to a local 1.4 > checkout, and have added a regression test that demonstrates the problem and > verifies the fix. > > if somebody feels strongly that this is too much of a functionality change for > a maintenance branch, please respond here on-list... otherwise, i'll commit > this to the 1.4 branch some time in the next day or so. whoops, forgot the patch: Index: Products/GenericSetup/tests/test_components.py =================================================================== --- Products/GenericSetup/tests/test_components.py (revision 91193) +++ Products/GenericSetup/tests/test_components.py (working copy) @@ -26,13 +26,17 @@ from Products.Five.component import enableSite from Products.Five.component.interfaces import IObjectManagerSite from zope.app.component.hooks import setSite, clearSite, setHooks +from zope.app.component.hooks import getSite +from zope.component import getMultiAdapter from zope.component import getSiteManager from zope.component import queryUtility from zope.component.globalregistry import base from zope.interface import implements from zope.interface import Interface +from Products.GenericSetup.interfaces import IBody from Products.GenericSetup.testing import BodyAdapterTestCase +from Products.GenericSetup.testing import DummySetupEnviron from Products.GenericSetup.testing import ExportImportZCMLLayer try: @@ -180,6 +184,30 @@ self._obj = sm self._BODY = _COMPONENTS_BODY + def test_no_overwrite(self): + # make sure we don't overwrite an existing tool when it + # already exists and has the same factory + context = DummySetupEnviron() + context._should_purge = False + importer = getMultiAdapter((self._obj, context), IBody) + importer.body = self._BODY # <-- triggers the import :( + + util = queryUtility(IDummyInterface) + value = 'bar' + util.foo = value + + # re-retrieve to make sure it's the same object + util = queryUtility(IDummyInterface) + self.assertEquals(getattr(util, 'foo', None), value) + + context = DummySetupEnviron() + context._should_purge = False + importer = getMultiAdapter((self._obj, context), IBody) + importer.body = self._BODY # <-- triggers the import :( + + util = queryUtility(IDummyInterface) + self.assertEquals(getattr(util, 'foo', None), value) + def tearDown(self): clearSite() Index: Products/GenericSetup/components.py =================================================================== --- Products/GenericSetup/components.py (revision 91193) +++ Products/GenericSetup/components.py (working copy) @@ -127,6 +127,8 @@ def _initUtilities(self, node): site = self._getSite() + current_utilities = self.context.registeredUtilities() + for child in node.childNodes: if child.nodeName != 'utility': continue @@ -163,7 +165,16 @@ elif component: self.context.registerUtility(component, provided, name) elif factory is not None: - self.context.registerUtility(factory(), provided, name) + current = [. utility for utility in current_utilities + if utility.provided==provided and + utility.name==name ] + assert len(current) <=1 + + new_utility = factory() + if current and type(current[0].component) == type(new_utility): + continue + + self.context.registerUtility(new_utility, provided, name) else: self._logger.warning("Invalid utility registration for " "interface %s" % provided) _______________________________________________ Zope-CMF maillist - Zope-CMF[at]lists.zope.org http://mail.zope.org/mailman/listinfo/zope-cmf See https://bugs.launchpad.net/zope-cmf/ for bug reports and feature requests
|