[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