[Checkins] SVN: zope.component/branches/conditional-zope.security/ merged the tlotze-hooks branch
Thomas Lotze
tl at gocept.com
Thu Oct 22 09:50:43 EDT 2009
Log message for revision 105213:
merged the tlotze-hooks branch
Changed:
U zope.component/branches/conditional-zope.security/CHANGES.txt
A zope.component/branches/conditional-zope.security/src/zope/component/hooks.py
A zope.component/branches/conditional-zope.security/src/zope/component/hooks.txt
U zope.component/branches/conditional-zope.security/src/zope/component/interfaces.py
U zope.component/branches/conditional-zope.security/src/zope/component/tests.py
-=-
Modified: zope.component/branches/conditional-zope.security/CHANGES.txt
===================================================================
--- zope.component/branches/conditional-zope.security/CHANGES.txt 2009-10-22 13:22:26 UTC (rev 105212)
+++ zope.component/branches/conditional-zope.security/CHANGES.txt 2009-10-22 13:50:42 UTC (rev 105213)
@@ -1,7 +1,7 @@
CHANGES
*******
-3.8.0dev (unreleased)
+3.8.0 (unreleased)
==================
- Removed the dependencies on zope.proxy and zope.security from the zcml extra:
@@ -9,6 +9,12 @@
proxied components ZCML registrations is enabled only if zope.security and
zope.proxy are available.
+- Moved the IPossibleSite and ISite interfaces here from zope.location as they
+ are dealing with zope.component's concept of a site, but not with location.
+
+- Moved the zope.site.hooks functionality to zope.component.hooks as it isn't
+ actually dealing with zope.site's concept of a site.
+
3.7.1 (2009-07-24)
==================
Copied: zope.component/branches/conditional-zope.security/src/zope/component/hooks.py (from rev 105209, zope.component/branches/tlotze-hooks/src/zope/component/hooks.py)
===================================================================
--- zope.component/branches/conditional-zope.security/src/zope/component/hooks.py (rev 0)
+++ zope.component/branches/conditional-zope.security/src/zope/component/hooks.py 2009-10-22 13:50:42 UTC (rev 105213)
@@ -0,0 +1,127 @@
+##############################################################################
+#
+# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Hooks for getting and setting a site in the thread global namespace.
+
+$Id$
+"""
+__docformat__ = 'restructuredtext'
+
+import threading
+import zope.component
+
+try:
+ import zope.security.proxy
+except ImportError:
+ SECURITY_SUPPORT = False
+else:
+ SECURITY_SUPPORT = True
+
+
+class read_property(object):
+ def __init__(self, func):
+ self.func = func
+
+ def __get__(self, inst, cls):
+ if inst is None:
+ return self
+
+ return self.func(inst)
+
+class SiteInfo(threading.local):
+ site = None
+ sm = zope.component.getGlobalSiteManager()
+
+ def adapter_hook(self):
+ adapter_hook = self.sm.adapters.adapter_hook
+ self.adapter_hook = adapter_hook
+ return adapter_hook
+
+ adapter_hook = read_property(adapter_hook)
+
+siteinfo = SiteInfo()
+
+def setSite(site=None):
+ if site is None:
+ sm = zope.component.getGlobalSiteManager()
+ else:
+
+ # We remove the security proxy because there's no way for
+ # untrusted code to get at it without it being proxied again.
+
+ # We should really look look at this again though, especially
+ # once site managers do less. There's probably no good reason why
+ # they can't be proxied. Well, except maybe for performance.
+
+ if SECURITY_SUPPORT:
+ site = zope.security.proxy.removeSecurityProxy(site)
+ # The getSiteManager method is defined by IPossibleSite.
+ sm = site.getSiteManager()
+
+ siteinfo.site = site
+ siteinfo.sm = sm
+ try:
+ del siteinfo.adapter_hook
+ except AttributeError:
+ pass
+
+def getSite():
+ return siteinfo.site
+
+
+def getSiteManager(context=None):
+ """A special hook for getting the site manager.
+
+ Here we take the currently set site into account to find the appropriate
+ site manager.
+ """
+ if context is None:
+ return siteinfo.sm
+
+ # We remove the security proxy because there's no way for
+ # untrusted code to get at it without it being proxied again.
+
+ # We should really look look at this again though, especially
+ # once site managers do less. There's probably no good reason why
+ # they can't be proxied. Well, except maybe for performance.
+ sm = zope.component.interfaces.IComponentLookup(
+ context, zope.component.getGlobalSiteManager())
+ if SECURITY_SUPPORT:
+ sm = zope.security.proxy.removeSecurityProxy(sm)
+ return sm
+
+
+def adapter_hook(interface, object, name='', default=None):
+ try:
+ return siteinfo.adapter_hook(interface, object, name, default)
+ except zope.component.interfaces.ComponentLookupError:
+ return default
+
+
+def setHooks():
+ zope.component.adapter_hook.sethook(adapter_hook)
+ zope.component.getSiteManager.sethook(getSiteManager)
+
+def resetHooks():
+ # Reset hookable functions to original implementation.
+ zope.component.adapter_hook.reset()
+ zope.component.getSiteManager.reset()
+
+# Clear the site thread global
+clearSite = setSite
+try:
+ from zope.testing.cleanup import addCleanUp
+except ImportError:
+ pass
+else:
+ addCleanUp(resetHooks)
Copied: zope.component/branches/conditional-zope.security/src/zope/component/hooks.txt (from rev 105209, zope.component/branches/tlotze-hooks/src/zope/component/hooks.txt)
===================================================================
--- zope.component/branches/conditional-zope.security/src/zope/component/hooks.txt (rev 0)
+++ zope.component/branches/conditional-zope.security/src/zope/component/hooks.txt 2009-10-22 13:50:42 UTC (rev 105213)
@@ -0,0 +1,65 @@
+==============================
+The current component registry
+==============================
+
+There can be any number of component registries in an application. One of them
+is the global component registry, and there is also the concept of a currently
+used component registry. Component registries other than the global one are
+associated with objects called sites. The ``zope.component.hooks`` module
+provides an API to set and access the current site as well as manipulate the
+adapter hook associated with it.
+
+As long as we haven't set a site, none is being considered current:
+
+>>> from zope.component.hooks import getSite
+>>> print getSite()
+None
+
+We can also ask for the current component registry (aka site manager
+historically); it will return the global one if no current site is set:
+
+>>> from zope.component.hooks import getSiteManager
+>>> getSiteManager()
+<BaseGlobalComponents base>
+
+Let's set a site now. A site has to be an object that provides the
+``getSiteManager`` method, which is specified by
+``zope.component.interfaces.IPossibleSite``:
+
+>>> from zope.component.registry import Components
+>>> class Site(object):
+... def __init__(self):
+... self.registry = Components('components')
+... def getSiteManager(self):
+... return self.registry
+
+>>> from zope.component.hooks import setSite
+>>> site1 = Site()
+>>> setSite(site1)
+
+After this, the newly set site is considered the currently active one:
+
+>>> getSite() is site1
+True
+>>> getSiteManager() is site1.registry
+True
+
+If we set another site, that one will be considered current:
+
+>>> site2 = Site()
+>>> site2.registry is not site1.registry
+True
+>>> setSite(site2)
+
+>>> getSite() is site2
+True
+>>> getSiteManager() is site2.registry
+True
+
+Finally we can unset the site and the global component registry is used again:
+
+>>> setSite()
+>>> print getSite()
+None
+>>> getSiteManager()
+<BaseGlobalComponents base>
Modified: zope.component/branches/conditional-zope.security/src/zope/component/interfaces.py
===================================================================
--- zope.component/branches/conditional-zope.security/src/zope/component/interfaces.py 2009-10-22 13:22:26 UTC (rev 105212)
+++ zope.component/branches/conditional-zope.security/src/zope/component/interfaces.py 2009-10-22 13:50:42 UTC (rev 105213)
@@ -923,3 +923,22 @@
class IComponents(IComponentLookup, IComponentRegistry):
"""Component registration and access
"""
+
+
+class IPossibleSite(Interface):
+ """An object that could be a site.
+ """
+
+ def setSiteManager(sitemanager):
+ """Sets the site manager for this object.
+ """
+
+ def getSiteManager():
+ """Returns the site manager contained in this object.
+
+ If there isn't a site manager, raise a component lookup.
+ """
+
+
+class ISite(IPossibleSite):
+ """Marker interface to indicate that we have a site"""
Modified: zope.component/branches/conditional-zope.security/src/zope/component/tests.py
===================================================================
--- zope.component/branches/conditional-zope.security/src/zope/component/tests.py 2009-10-22 13:22:26 UTC (rev 105212)
+++ zope.component/branches/conditional-zope.security/src/zope/component/tests.py 2009-10-22 13:50:42 UTC (rev 105213)
@@ -1682,6 +1682,9 @@
zcml_conditional = doctest.DocFileSuite('zcml_conditional.txt', checker=checker)
zcml_conditional.layer = ConditionalSecurityLayer()
+ hooks_conditional = doctest.DocFileSuite('hooks.txt', checker=checker)
+ hooks_conditional.layer = ConditionalSecurityLayer()
+
return unittest.TestSuite((
doctest.DocTestSuite(setUp=setUp, tearDown=tearDown),
unittest.makeSuite(HookableTests),
@@ -1697,11 +1700,14 @@
doctest.DocFileSuite('registry.txt', checker=checker,
setUp=setUpRegistryTests,
tearDown=tearDownRegistryTests),
+ doctest.DocFileSuite('hooks.txt',checker=checker,
+ setUp=setUp, tearDown=tearDown),
doctest.DocFileSuite('event.txt',
setUp=setUp, tearDown=tearDown),
doctest.DocFileSuite('zcml.txt', checker=checker,
setUp=setUp, tearDown=tearDown),
zcml_conditional,
+ hooks_conditional,
unittest.makeSuite(StandaloneTests),
unittest.makeSuite(ResourceViewTests),
))
More information about the checkins
mailing list