[Zope3-checkins] SVN: Zope3/trunk/
zope.tales.expressions.simpleTraverse would raise NameError if the
Stefan H. Holek
stefan at epy.co.at
Sun Nov 20 08:23:13 EST 2005
Log message for revision 40270:
zope.tales.expressions.simpleTraverse would raise NameError if the
object at hand did not implement __getitem__. Changed to raise
AttributeError instead. AttributeError is included in Undefs whereas
NameError is not.
Changed:
U Zope3/trunk/doc/CHANGES.txt
U Zope3/trunk/src/zope/tales/expressions.py
U Zope3/trunk/src/zope/tales/tests/test_expressions.py
A Zope3/trunk/src/zope/tales/tests/test_traverser.py
-=-
Modified: Zope3/trunk/doc/CHANGES.txt
===================================================================
--- Zope3/trunk/doc/CHANGES.txt 2005-11-20 12:46:15 UTC (rev 40269)
+++ Zope3/trunk/doc/CHANGES.txt 2005-11-20 13:23:13 UTC (rev 40270)
@@ -154,6 +154,11 @@
Bug Fixes
+ - zope.tales.expressions.simpleTraverse would raise NameError if the
+ object at hand did not implement __getitem__. Changed to raise
+ AttributeError instead. AttributeError is included in Undefs whereas
+ NameError is not.
+
- Fixed bug 405, http://www.zope.org/Collectors/Zope3-dev/405
Needed check for common bug when calling apply on field indexes.
@@ -206,7 +211,7 @@
Stephan Richter, Roger Ineichen, Marius Gedminas, Julien Anguenot, Benji
York, Gary Poster, Jim Fulton, Michael Kerrin, Torsten Kurbad,
Philipp von Weitershausen, Tarek Ziadé, Andreas Jung, Dmitry Vasiliev,
- Juergen Kartnaller
+ Juergen Kartnaller, Stefan Holek
Note: If you are not listed and contributed, please add yourself. This
note will be deleted before the release.
Modified: Zope3/trunk/src/zope/tales/expressions.py
===================================================================
--- Zope3/trunk/src/zope/tales/expressions.py 2005-11-20 12:46:15 UTC (rev 40269)
+++ Zope3/trunk/src/zope/tales/expressions.py 2005-11-20 13:23:13 UTC (rev 40270)
@@ -37,7 +37,8 @@
elif hasattr(object, '__getitem__'):
object = object[name]
else:
- raise NameError(name)
+ # Allow AttributError to propagate
+ object = getattr(object, name)
return object
Modified: Zope3/trunk/src/zope/tales/tests/test_expressions.py
===================================================================
--- Zope3/trunk/src/zope/tales/tests/test_expressions.py 2005-11-20 12:46:15 UTC (rev 40269)
+++ Zope3/trunk/src/zope/tales/tests/test_expressions.py 2005-11-20 13:23:13 UTC (rev 40270)
@@ -260,7 +260,7 @@
try:
expr = self.engine.compile('adapterTest/namespace:title')
expr(self.context)
- except (NameError,KeyError),e:
+ except KeyError,e:
self.assertEquals(e.args[0],'title')
else:
self.fail('Engine accepted unknown function')
Added: Zope3/trunk/src/zope/tales/tests/test_traverser.py
===================================================================
--- Zope3/trunk/src/zope/tales/tests/test_traverser.py 2005-11-20 12:46:15 UTC (rev 40269)
+++ Zope3/trunk/src/zope/tales/tests/test_traverser.py 2005-11-20 13:23:13 UTC (rev 40270)
@@ -0,0 +1,120 @@
+"""
+Tests for zope.tales.expressions.simpleTraverse
+
+$Id:$
+"""
+
+from unittest import TestCase, TestSuite, makeSuite, main
+from zope.tales.expressions import simpleTraverse
+
+
+class AttrTraversable(object):
+ """Traversable by attribute access"""
+ attr = 'foo'
+
+class ItemTraversable(object):
+ """Traversable by item access"""
+ def __getitem__(self, name):
+ if name == 'attr':
+ return 'foo'
+ raise KeyError, name
+
+class AllTraversable(AttrTraversable, ItemTraversable):
+ """Traversable by attribute and item access"""
+ pass
+
+
+_marker = object()
+
+def getitem(ob, name, default=_marker):
+ """Helper a la getattr(ob, name, default)."""
+ try:
+ item = ob[name]
+ except KeyError:
+ if default is not _marker:
+ return default
+ raise KeyError, name
+ else:
+ return item
+
+
+class TraverserTests(TestCase):
+
+ def testGetItem(self):
+ # getitem helper should behave like __getitem__
+ ob = {'attr': 'foo'}
+ self.assertEqual(getitem(ob, 'attr', None), 'foo')
+ self.assertEqual(getitem(ob, 'attr'), 'foo')
+ self.assertEqual(getitem(ob, 'missing_attr', None), None)
+ self.assertRaises(KeyError, getitem, ob, 'missing_attr')
+ self.assertRaises(TypeError, getitem, object(), 'attr')
+
+ def testAttrTraversable(self):
+ # An object without __getitem__ should raise AttributeError
+ # for missing attribute.
+ ob = AttrTraversable()
+ self.assertEqual(getattr(ob, 'attr', None), 'foo')
+ self.assertRaises(AttributeError, getattr, ob, 'missing_attr')
+
+ def testItemTraversable(self):
+ # An object with __getitem__ (but without attr) should raise
+ # KeyError for missing attribute.
+ ob = ItemTraversable()
+ self.assertEqual(getitem(ob, 'attr', None), 'foo')
+ self.assertRaises(KeyError, getitem, ob, 'missing_attr')
+
+ def testAllTraversable(self):
+ # An object with attr and __getitem__ should raise either
+ # exception, depending on method of access.
+ ob = AllTraversable()
+ self.assertEqual(getattr(ob, 'attr', None), 'foo')
+ self.assertRaises(AttributeError, getattr, ob, 'missing_attr')
+ self.assertEqual(getitem(ob, 'attr', None), 'foo')
+ self.assertRaises(KeyError, getitem, ob, 'missing_attr')
+
+ def testTraverseEmptyPath(self):
+ # simpleTraverse should return the original object if the path is emtpy
+ ob = object()
+ self.assertEqual(simpleTraverse(ob, [], None), ob)
+
+ def testTraverseByAttr(self):
+ # simpleTraverse should find attr through attribute access
+ ob = AttrTraversable()
+ self.assertEqual(simpleTraverse(ob, ['attr'], None), 'foo')
+
+ def testTraverseByMissingAttr(self):
+ # simpleTraverse should raise AttributeError
+ ob = AttrTraversable()
+ # Here lurks the bug (unexpected NamError raised)
+ self.assertRaises(AttributeError, simpleTraverse, ob, ['missing_attr'], None)
+
+ def testTraverseByItem(self):
+ # simpleTraverse should find attr through item access
+ ob = ItemTraversable()
+ self.assertEqual(simpleTraverse(ob, ['attr'], None), 'foo')
+
+ def testTraverseByMissingItem(self):
+ # simpleTraverse should raise KeyError
+ ob = ItemTraversable()
+ self.assertRaises(KeyError, simpleTraverse, ob, ['missing_attr'], None)
+
+ def testTraverseByAll(self):
+ # simpleTraverse should find attr through attribute access
+ ob = AllTraversable()
+ self.assertEqual(simpleTraverse(ob, ['attr'], None), 'foo')
+
+ def testTraverseByMissingAll(self):
+ # simpleTraverse should raise KeyError (because ob implements __getitem__)
+ ob = AllTraversable()
+ self.assertRaises(KeyError, simpleTraverse, ob, ['missing_attr'], None)
+
+
+def test_suite():
+ return TestSuite((
+ makeSuite(TraverserTests),
+ ))
+
+
+if __name__ == '__main__':
+ main(defaultTest='test_suite')
+
Property changes on: Zope3/trunk/src/zope/tales/tests/test_traverser.py
___________________________________________________________________
Name: svn:keywords
+ Id
Name: svn:eol-style
+ native
More information about the Zope3-Checkins
mailing list