summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/zope/pagetemplate/engine.py22
1 files changed, 22 insertions, 0 deletions
diff --git a/src/zope/pagetemplate/engine.py b/src/zope/pagetemplate/engine.py
index 99634fa..df307e7 100644
--- a/src/zope/pagetemplate/engine.py
+++ b/src/zope/pagetemplate/engine.py
@@ -22,6 +22,7 @@ import sys
from zope import component
from zope.interface import implementer
from zope.component.interfaces import ComponentLookupError
+from zope.proxy import isProxy
from zope.traversing.interfaces import IPathAdapter, ITraversable
from zope.traversing.interfaces import TraversalError
from zope.traversing.adapters import traversePathElement
@@ -66,6 +67,8 @@ class ZopeTraverser(object):
# special-case dicts for performance reasons
if getattr(object, '__class__', None) == dict:
object = object[name]
+ elif isinstance(object, dict) and not isProxy(object):
+ object = object[name]
else:
object = traversePathElement(object, name, path_items,
request=request)
@@ -386,6 +389,25 @@ class ZopeEngine(ZopeBaseEngine):
...
KeyError: 'keys'
+ This special-casing also applies to non-proxied dict subclasses:
+
+ >>> class TraverserDict(dict):
+ ... def __init__(self):
+ ... self.item_requested = None
+ ... def __getitem__(self, item):
+ ... self.item_requested = item
+ ... return dict.__getitem__(self, item)
+
+ >>> d = engine.getBaseNames()
+ >>> foo = TraverserDict()
+ >>> d['foo'] = foo
+ >>> foo['bar'] = 'baz'
+ >>> context = engine.getContext(d)
+ >>> context.evaluate('foo/bar')
+ 'baz'
+ >>> foo.item_requested
+ 'bar'
+
>>> tearDown()
"""