[Checkins] SVN: zope.component/trunk/ Merge the 'tseaver-wo_zope_deferredimport' branch:

Tres Seaver tseaver at palladion.com
Wed Mar 4 19:02:34 EST 2009


Log message for revision 97501:
  Merge the 'tseaver-wo_zope_deferredimport' branch:
  
  - Added a pure-Python 'hookable' implementation, for use when
    'zope.hookable' is not present.
  
  - Undeprecated the interfaces in the 'bbb' package:  the promised
    removal hasn't happened, and other core pacakges are still using
    them.  Moved them into ``zope.component.interfaces``, their original
    location, and the one from which consumers have been importing them.
  
  - Removed use of 'zope.deferredimport' by breaking import cycles.
  

Changed:
  U   zope.component/trunk/CHANGES.txt
  U   zope.component/trunk/buildout.cfg
  U   zope.component/trunk/src/zope/component/_api.py
  A   zope.component/trunk/src/zope/component/hookable.py
  U   zope.component/trunk/src/zope/component/interfaces.py
  U   zope.component/trunk/src/zope/component/tests.py

-=-
Modified: zope.component/trunk/CHANGES.txt
===================================================================
--- zope.component/trunk/CHANGES.txt	2009-03-05 00:01:45 UTC (rev 97500)
+++ zope.component/trunk/CHANGES.txt	2009-03-05 00:02:34 UTC (rev 97501)
@@ -4,6 +4,16 @@
 3.6.0 (unreleased)
 ==================
 
+- Added a pure-Python 'hookable' implementation, for use when
+  'zope.hookable' is not present.
+
+- Undeprecated the interfaces in the 'bbb' package:  the promised
+  removal hasn't happened, and other core pacakges are still using
+  them.  Moved them into ``zope.component.interfaces``, their original
+  location, and the one from which consumers have been importing them.
+
+- Removed use of 'zope.deferredimport' by breaking import cycles.
+
 - Cleanup package documentation and changelog a bit. Add sphinx-based
   documentation building command to the buildout.
 

Modified: zope.component/trunk/buildout.cfg
===================================================================
--- zope.component/trunk/buildout.cfg	2009-03-05 00:01:45 UTC (rev 97500)
+++ zope.component/trunk/buildout.cfg	2009-03-05 00:02:34 UTC (rev 97501)
@@ -1,11 +1,16 @@
 [buildout]
 develop = .
-parts = test python docs
+parts = test test_c_hookable python docs
+unzip = true
 
 [test]
 recipe = zc.recipe.testrunner
 eggs = zope.component [test,zcml]
 
+[test_c_hookable]
+recipe = zc.recipe.testrunner
+eggs = zope.component [test,zcml,hook]
+
 [python]
 recipe = zc.recipe.egg
 interpreter = python

Modified: zope.component/trunk/src/zope/component/_api.py
===================================================================
--- zope.component/trunk/src/zope/component/_api.py	2009-03-05 00:01:45 UTC (rev 97500)
+++ zope.component/trunk/src/zope/component/_api.py	2009-03-05 00:02:34 UTC (rev 97501)
@@ -28,12 +28,12 @@
 from zope.component.globalregistry import base
 from zope.component._declaration import adapter, adapts, adaptedBy
 
-# Try to be hookable. Do so in a try/except to avoid a hard dependency.
+# Use the C implementation in zope.hookable, if available;  fall back
+# to our Python version if not.
 try:
     from zope.hookable import hookable
 except ImportError:
-    def hookable(ob):
-        return ob
+    from zope.component.hookable import hookable
 
 # getSiteManager() returns a component registry.  Although the term
 # "site manager" is deprecated in favor of "component registry",

Copied: zope.component/trunk/src/zope/component/hookable.py (from rev 97498, zope.component/branches/tseaver-wo_zope_deferred/src/zope/component/hookable.py)
===================================================================
--- zope.component/trunk/src/zope/component/hookable.py	                        (rev 0)
+++ zope.component/trunk/src/zope/component/hookable.py	2009-03-05 00:02:34 UTC (rev 97501)
@@ -0,0 +1,33 @@
+##############################################################################
+#
+# Copyright (c) 2009 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.
+#
+##############################################################################
+""" This module supplies a pure-Python version of zope.hookable.hookable.
+"""
+class hookable(object):
+    __slots__ = ('__original', '__implementation')
+
+    original = property(lambda self: self.__original,)
+    implementation = property(lambda self: self.__implementation,)
+
+    def __init__(self, implementation):
+        self.__original = self.__implementation = implementation
+
+    def sethook(self, newimplementation):
+        old, self.__implementation = self.__implementation, newimplementation
+        return old
+
+    def reset(self):
+        self.__implementation = self.__original
+
+    def __call__(self, *args, **kw):
+        return self.__implementation(*args, **kw)

Modified: zope.component/trunk/src/zope/component/interfaces.py
===================================================================
--- zope.component/trunk/src/zope/component/interfaces.py	2009-03-05 00:01:45 UTC (rev 97500)
+++ zope.component/trunk/src/zope/component/interfaces.py	2009-03-05 00:02:34 UTC (rev 97501)
@@ -15,6 +15,7 @@
 
 $Id$
 """
+__docformat__ = "reStructuredText"
 
 import zope.deferredimport
 from zope import interface
@@ -910,3 +911,75 @@
 class IComponents(IComponentLookup, IComponentRegistry):
     """Component registration and access
     """
+
+
+class IContextDependent(Interface):
+    """Components implementing this interface must have a context component.
+
+    Usually the context must be one of the arguments of the
+    constructor. Adapters and views are a primary example of context-dependent
+    components.
+    """
+
+    context = Attribute(
+        """The context of the object
+
+        This is the object being adapted, viewed, extended, etc.
+        """)
+
+
+class IPresentation(Interface):
+    """Presentation components provide interfaces to external actors
+
+    The are created for requests, which encapsulate external actors,
+    connections, etc.
+    """
+
+    request = Attribute(
+        """The request
+
+        The request is a surrogate for the user. It also provides the
+        presentation type and skin. It is of type
+        IPresentationRequest.
+        """)
+
+
+class IPresentationRequest(Interface):
+    """An IPresentationRequest provides methods for getting view meta data."""
+
+
+class IResource(IPresentation):
+    """Resources provide data to be used for presentation."""
+
+
+class IResourceFactory(Interface):
+    """A factory to create factories using the request."""
+
+    def __call__(request):
+        """Create a resource for a request
+
+        The request must be an IPresentationRequest.
+        """
+
+
+class IView(IPresentation, IContextDependent):
+    """Views provide a connection between an external actor and an object"""
+
+
+class IViewFactory(Interface):
+    """Objects for creating views"""
+
+    def __call__(context, request):
+        """Create an view (IView) object
+
+        The context aregument is the object displayed by the view. The
+        request argument is an object, such as a web request, that
+        "stands in" for the user.
+        """
+
+class IDefaultViewName(Interface):
+    """A string that contains the default view name
+
+    A default view name is used to select a view when a user hasn't
+    specified one.
+    """

Modified: zope.component/trunk/src/zope/component/tests.py
===================================================================
--- zope.component/trunk/src/zope/component/tests.py	2009-03-05 00:01:45 UTC (rev 97500)
+++ zope.component/trunk/src/zope/component/tests.py	2009-03-05 00:02:34 UTC (rev 97501)
@@ -1,6 +1,6 @@
 ##############################################################################
 #
-# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
+# Copyright (c) 2001, 2002, 2009 Zope Corporation and Contributors.
 # All Rights Reserved.
 #
 # This software is subject to the provisions of the Zope Public License,
@@ -993,6 +993,116 @@
         if not success:
             self.fail(''.join(lines))
 
+class HookableTests(unittest.TestCase):
+
+    def test_ctor_no_func(self):
+        from zope.component.hookable import hookable
+        self.assertRaises(TypeError, hookable)
+
+    def test_ctor_simple(self):
+        from zope.component.hookable import hookable
+        def foo():
+            pass
+        hooked = hookable(foo)
+        self.failUnless(hooked.original is foo)
+        self.failUnless(hooked.implementation is foo)
+
+    def test_ctor_extra_arg(self):
+        from zope.component.hookable import hookable
+        def foo():
+            pass
+        self.assertRaises(TypeError, hookable, foo, foo)
+
+    def test_ctor_extra_arg(self):
+        from zope.component.hookable import hookable
+        def foo():
+            pass
+        self.assertRaises(TypeError, hookable, foo, nonesuch=foo)
+
+    def test_sethook(self):
+        from zope.component.hookable import hookable
+        def foo():
+            pass
+        def bar():
+            pass
+        hooked = hookable(foo)
+        hooked.sethook(bar)
+        self.failUnless(hooked.original is foo)
+        self.failUnless(hooked.implementation is bar)
+
+    def test_reset(self):
+        from zope.component.hookable import hookable
+        def foo():
+            pass
+        def bar():
+            pass
+        hooked = hookable(foo)
+        hooked.sethook(bar)
+        hooked.reset()
+        self.failUnless(hooked.original is foo)
+        self.failUnless(hooked.implementation is foo)
+
+    def test_cant_assign_original(self):
+        from zope.component.hookable import hookable
+        def foo():
+            pass
+        def bar():
+            pass
+        hooked = hookable(foo)
+        try:
+            hooked.original = bar
+        except TypeError:
+            pass
+        except AttributeError:
+            pass
+        else:
+            self.fail('Assigned original')
+
+    def test_cant_delete_original(self):
+        from zope.component.hookable import hookable
+        def foo():
+            pass
+        hooked = hookable(foo)
+        try:
+            del hooked.original
+        except TypeError:
+            pass
+        except AttributeError:
+            pass
+        else:
+            self.fail('Deleted original')
+
+    def test_cant_assign_original(self):
+        from zope.component.hookable import hookable
+        def foo():
+            pass
+        def bar():
+            pass
+        hooked = hookable(foo)
+        try:
+            hooked.implementation = bar
+        except TypeError:
+            pass
+        except AttributeError:
+            pass
+        else:
+            self.fail('Assigned implementation')
+
+    def test_readonly_original(self):
+        from zope.component.hookable import hookable
+        def foo():
+            pass
+        hooked = hookable(foo)
+        try:
+            del hooked.implementation
+        except TypeError:
+            pass
+        except AttributeError:
+            pass
+        else:
+            self.fail('Deleted implementation')
+
+
 def setUpRegistryTests(tests):
     setUp()
 



More information about the Checkins mailing list