[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