On Thu, Apr 08, 2010 at 02:37:33PM -0400, Chris McDonough wrote: > Not sure how a new layer setup and teardown is signaled but assuming you can > hook that, do something like this: > > class StackManager(object): > def __init__(self, default=None): > self.stack = [] > self.default = default > > def push(self, info): > self.stack.append(info) > > def pop(self): > if self.stack: > return self.stack.pop() > > def get(self): > try: > return self.stack[-1] > except IndexError: > return self.default() > > def clear(self): > self.stack[:] = [] > > from zope.component import getGlobalSiteManager > global_registry = getGlobalSiteManager() > > def defaults(): > return {'registry':global_registry} > > manager = StackManager(default=defaults) > > def get_current_registry(context=None): > return manager.get()['registry'] > > from zope.component import getSiteManager > getSiteManager.sethook(get_current_registry)
That seems a bit short-sighted: it would break all tests that rely on setSite() working. > > Then when a layer is pushed: > > from zope.comonent.registry import Components > manager.push({'registry':Components()}) I suspect Martin wants manager.push({'registry': Components(bases=[manager.get()])}) here. > > And popped: > > manager.pop() > > > On 4/8/10 1:26 PM, Martin Aspeli wrote: > > Hi, > > > > I'd like to come up with a way to set up a test fixture that does the > > component registry equivalent of stackable DemoStorage's: whilst a layer > > is in effect, calls to provideAdapter() and friends (and ZCML execution) > > go into a global registry that is stacked on top of the default global one.o Someone (I'm bad with names, sorry!) recently proposed a change to zope.configuration that makes ZCML directives use getSiteManager() instead of getGlobalSiteManager(); with that patch in, Chris's example should make ZCML configuration register all the components into your stacked registry. Although you'd have the other problem of setSite() having no effect on the site manager, which would break all local utilities and adapters in your tests. provideAdapter is harder, since it hardcodes the global registry. You'd have to monkey-patch the `base` global, or fix provideAdapter and friends. > > > > On layer tear-down, the registry is popped, leaving the original (or > > previous) global registry intact. I like this goal. > > > > In zope.component.globalregistry, I see: > > > > def provideUtility(component, provides=None, name=u''): > > base.registerUtility(component, provides, name, event=False) > > > > base is a module-level variable of type BaseGlobalComponents(). I guess > > there'd be a way to use __bases__ to create this kind of stack, but I'm > > not clear on the details, and in particular whether this would really > > work with provideAdapter() and the rest of the (test-oriented) Python API. I don't see any way around monkey-patching zope.component.globalregistry.base/globalSiteManager (two names for the same object for extra fun!). Also note that the root folder in the database has a local site manager with __bases__ directly referencing the global site object, which is pickled by name. If you replace it, you'll need to use a different BaseGlobalComponents instance, I think. Marius Gedminas -- http://pov.lt/ -- Zope 3 consulting and development
signature.asc
Description: Digital signature
_______________________________________________ Zope-Dev maillist - Zope-Dev@zope.org https://mail.zope.org/mailman/listinfo/zope-dev ** No cross posts or HTML encoding! ** (Related lists - https://mail.zope.org/mailman/listinfo/zope-announce https://mail.zope.org/mailman/listinfo/zope )