[Checkins] SVN: zope.component/branches/tseaver-wo_zope_deferred/ Added a pure-Python 'hookable' implementation, for use when 'zope.hookable'
Tres Seaver
tseaver at palladion.com
Wed Mar 4 18:29:00 EST 2009
Log message for revision 97498:
Added a pure-Python 'hookable' implementation, for use when 'zope.hookable'
is not present.
Changed:
U zope.component/branches/tseaver-wo_zope_deferred/CHANGES.txt
U zope.component/branches/tseaver-wo_zope_deferred/buildout.cfg
U zope.component/branches/tseaver-wo_zope_deferred/src/zope/component/_api.py
A zope.component/branches/tseaver-wo_zope_deferred/src/zope/component/hookable.py
U zope.component/branches/tseaver-wo_zope_deferred/src/zope/component/tests.py
-=-
Modified: zope.component/branches/tseaver-wo_zope_deferred/CHANGES.txt
===================================================================
--- zope.component/branches/tseaver-wo_zope_deferred/CHANGES.txt 2009-03-04 23:17:08 UTC (rev 97497)
+++ zope.component/branches/tseaver-wo_zope_deferred/CHANGES.txt 2009-03-04 23:29:00 UTC (rev 97498)
@@ -4,6 +4,9 @@
3.6.0 (unreleased)
==================
+- Added a pure-Python 'hookable' implementation, for use when
+ 'zope.hookable' is not present.
+
- Cleanup package documentation and changelog a bit. Add sphinx-based
documentation building command to the buildout.
Modified: zope.component/branches/tseaver-wo_zope_deferred/buildout.cfg
===================================================================
--- zope.component/branches/tseaver-wo_zope_deferred/buildout.cfg 2009-03-04 23:17:08 UTC (rev 97497)
+++ zope.component/branches/tseaver-wo_zope_deferred/buildout.cfg 2009-03-04 23:29:00 UTC (rev 97498)
@@ -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/branches/tseaver-wo_zope_deferred/src/zope/component/_api.py
===================================================================
--- zope.component/branches/tseaver-wo_zope_deferred/src/zope/component/_api.py 2009-03-04 23:17:08 UTC (rev 97497)
+++ zope.component/branches/tseaver-wo_zope_deferred/src/zope/component/_api.py 2009-03-04 23:29:00 UTC (rev 97498)
@@ -31,12 +31,12 @@
from zope.component._declaration import adapter
from zope.component._declaration import adapts
-# 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",
Added: zope.component/branches/tseaver-wo_zope_deferred/src/zope/component/hookable.py
===================================================================
--- zope.component/branches/tseaver-wo_zope_deferred/src/zope/component/hookable.py (rev 0)
+++ zope.component/branches/tseaver-wo_zope_deferred/src/zope/component/hookable.py 2009-03-04 23:29:00 UTC (rev 97498)
@@ -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/branches/tseaver-wo_zope_deferred/src/zope/component/tests.py
===================================================================
--- zope.component/branches/tseaver-wo_zope_deferred/src/zope/component/tests.py 2009-03-04 23:17:08 UTC (rev 97497)
+++ zope.component/branches/tseaver-wo_zope_deferred/src/zope/component/tests.py 2009-03-04 23:29:00 UTC (rev 97498)
@@ -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,
@@ -987,6 +987,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