Re: [Zope-dev] Stacking zope.component registries

2010-04-09 Thread Marius Gedminas
On Thu, Apr 08, 2010 at 10:15:22PM -0400, Stephan Richter wrote:
 On Thursday 08 April 2010, Martin Aspeli wrote:
  Right. However, any calls to provideAdapter() and friends would still 
  use the global registry, unless I monkey patch 
  zope.component.globalregistry.base, as would any ZCML directives, I guess.
 
 That's not really monkey patching. :-) I would consider this a valid part of 
 the API. :-)

Then it's _badly-designed_ API.  Look at globalregistry.py from
zope.component 3.4.0:

  base = BaseGlobalComponents('base')

  from zope.testing.cleanup import addCleanUp
  addCleanUp(lambda: base.__init__('base'))

  globalSiteManager = base
  def getGlobalSiteManager():
  return globalSiteManager

  def provideAdapter(factory, adapts=None, provides=None, name=''):
  base.registerAdapter(factory, adapts, provides, name, event=False)

  ...

There are two names for the same thing: 'base' and 'globalSiteManager'.
Different methods use different names.  There's an assumption that you
can call __init__ on it before and after every test that uses placeless
setup.  (I hadn't noticed that last part before; I assume it'll override
base.__bases__ and destroy any attempts of stacking.)

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 )


[Zope-dev] Stacking zope.component registries

2010-04-08 Thread Martin Aspeli
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.

On layer tear-down, the registry is popped, leaving the original (or 
previous) global registry intact.

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.

Martin

___
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 )


Re: [Zope-dev] Stacking zope.component registries

2010-04-08 Thread Chris McDonough
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)

Then when a layer is pushed:

   from zope.comonent.registry import Components
   manager.push({'registry':Components()})

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.

 On layer tear-down, the registry is popped, leaving the original (or
 previous) global registry intact.

 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.

 Martin

 ___
 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 )



-- 
Chris McDonough
Agendaless Consulting, Fredericksburg VA
The repoze.bfg Web Application Framework Book: http://bfg.repoze.org/book
___
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 )


Re: [Zope-dev] Stacking zope.component registries

2010-04-08 Thread Marius Gedminas
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 )


Re: [Zope-dev] Stacking zope.component registries

2010-04-08 Thread Stephan Richter
On Thursday 08 April 2010, Marius Gedminas wrote:
 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.

What about using z3c.baseregistry? You can wrap the baseregistry call around 
your ZCML. This way you can create on registry per layer and then use the 
__bases__ attribute to stack them together.

Regards.
Stephan
-- 
Entrepreneur and Software Geek
Google me. Zope Stephan Richter
___
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 )


Re: [Zope-dev] Stacking zope.component registries

2010-04-08 Thread Chris McDonough
On 4/8/10 4:36 PM, Marius Gedminas wrote:

 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.

He said he wanted a global registry, but.. who knows?  I stay as far away from 
that API as possible. ;-)
___
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 )


Re: [Zope-dev] Stacking zope.component registries

2010-04-08 Thread Martin Aspeli
Stephan Richter wrote:
 On Thursday 08 April 2010, Marius Gedminas wrote:
 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.

 What about using z3c.baseregistry? You can wrap the baseregistry call around
 your ZCML. This way you can create on registry per layer and then use the
 __bases__ attribute to stack them together.

Yes, I did look at it. However, the real goal is to provide isolation 
for anything that makes ZCA registrations. In particular, that 
includes provideAdapter() and friends. I suspect z3c.baseregistry can't 
deal with this?

Martin

-- 
Author of `Professional Plone Development`, a book for developers who
want to work with Plone. See http://martinaspeli.net/plone-book

___
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 )


Re: [Zope-dev] Stacking zope.component registries

2010-04-08 Thread Martin Aspeli
Chris McDonough wrote:
 On 4/8/10 4:36 PM, Marius Gedminas wrote:
 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.

 He said he wanted a global registry, but.. who knows?  I stay as far away from
 that API as possible. ;-)

Marius is right - I need standard stuff like setSite(), local components 
and that pesky global API (provideAdapter etc.) to work.

Martin

-- 
Author of `Professional Plone Development`, a book for developers who
want to work with Plone. See http://martinaspeli.net/plone-book

___
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 )


Re: [Zope-dev] Stacking zope.component registries

2010-04-08 Thread Stephan Richter
On Thursday 08 April 2010, Martin Aspeli wrote:
 Yes, I did look at it. However, the real goal is to provide isolation 
 for anything that makes ZCA registrations. In particular, that 
 includes provideAdapter() and friends. I suspect z3c.baseregistry can't 
 deal with this?

I think it can be done, just not in the way I intended it to. Instead of 
adding the base registry to bases, you have to make it the actual registry for 
the API, which should be no problem from a functional test setup function.

Regards,
Stephan
-- 
Entrepreneur and Software Geek
Google me. Zope Stephan Richter
___
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 )


Re: [Zope-dev] Stacking zope.component registries

2010-04-08 Thread Martin Aspeli
Stephan Richter wrote:
 On Thursday 08 April 2010, Martin Aspeli wrote:
 Yes, I did look at it. However, the real goal is to provide isolation
 for anything that makes ZCA registrations. In particular, that
 includes provideAdapter() and friends. I suspect z3c.baseregistry can't
 deal with this?

 I think it can be done, just not in the way I intended it to. Instead of
 adding the base registry to bases, you have to make it the actual registry for
 the API, which should be no problem from a functional test setup function.

Can you elaborate on what you mean here?

Martin

-- 
Author of `Professional Plone Development`, a book for developers who
want to work with Plone. See http://martinaspeli.net/plone-book

___
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 )


Re: [Zope-dev] Stacking zope.component registries

2010-04-08 Thread Stephan Richter
On Thursday 08 April 2010, Martin Aspeli wrote:
 Can you elaborate on what you mean here?

So I think this can all be done independently of base registry (unless you are 
are planning to store the registry in the ZODB).

The key for layering is the ability to inherit components using the __bases__ 
attribute (see registry.py). So something like:

reg1 = Components('reg1') # Registry for layer 1

Then for the next layer that is based on layer 1, you can do:

reg2 = Components('reg2', (reg1,)) # Registry for layer 2

This should behave identically to how ZODB storage layering works.

Regards,
Stephan
-- 
Entrepreneur and Software Geek
Google me. Zope Stephan Richter
___
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 )


Re: [Zope-dev] Stacking zope.component registries

2010-04-08 Thread Martin Aspeli
Stephan Richter wrote:
 On Thursday 08 April 2010, Martin Aspeli wrote:
 Can you elaborate on what you mean here?

 So I think this can all be done independently of base registry (unless you are
 are planning to store the registry in the ZODB).

 The key for layering is the ability to inherit components using the __bases__
 attribute (see registry.py). So something like:

 reg1 = Components('reg1') # Registry for layer 1

 Then for the next layer that is based on layer 1, you can do:

 reg2 = Components('reg2', (reg1,)) # Registry for layer 2

 This should behave identically to how ZODB storage layering works.

Right. However, any calls to provideAdapter() and friends would still 
use the global registry, unless I monkey patch 
zope.component.globalregistry.base, as would any ZCML directives, I guess.

Martin

-- 
Author of `Professional Plone Development`, a book for developers who
want to work with Plone. See http://martinaspeli.net/plone-book

___
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 )


Re: [Zope-dev] Stacking zope.component registries

2010-04-08 Thread Stephan Richter
On Thursday 08 April 2010, Martin Aspeli wrote:
 Right. However, any calls to provideAdapter() and friends would still 
 use the global registry, unless I monkey patch 
 zope.component.globalregistry.base, as would any ZCML directives, I guess.

That's not really monkey patching. :-) I would consider this a valid part of 
the API. :-)

Regards,
Stephan
-- 
Entrepreneur and Software Geek
Google me. Zope Stephan Richter
___
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 )