[ZPT] CVS: Packages/Products/PageTemplates (Products/DC/PageTemplates) - TALES.py:1.7.2.3

evan@serenade.digicool.com evan@serenade.digicool.com
Tue, 8 May 2001 14:14:11 -0400


Update of /cvs-repository/Packages/Products/PageTemplates
In directory serenade.digicool.com:/home/evan/Zope/pt/lib/python/Products/PageTemplates

Modified Files:
      Tag: zpt-1_2
	TALES.py 
Log Message:
Improve use of MultiMapping



--- Updated File TALES.py in package Packages/Products/PageTemplates --
--- TALES.py	2001/05/08 01:55:15	1.7.2.2
+++ TALES.py	2001/05/08 18:14:11	1.7.2.3
@@ -121,24 +121,28 @@
 class CompilerError(Exception):
     '''TALES Compiler Error'''
 
-class SecureMultiMap:
-    '''MultiMapping wrapper with security declarations'''
+_marker = []
+
+class SafeMapping(MultiMapping):
+    '''Mapping with security declarations and limited method exposure.
+
+    Since it subclasses MultiMapping, this class can be used to wrap
+    one or more mapping objects.  Restricted Python code will not be
+    able to mutate the SafeMapping or the wrapped mappings, but will be
+    able to read any value.
+    '''
     __allow_access_to_unprotected_subobjects__ = 1
-    def __init__(self, *dicts):
-        self._mm = apply(MultiMapping, dicts)
-    def __getitem__(self, index):
-        return self._mm[index]
-    def __len__(self):
-        return len(self._mm)
-    def _push(self, arg):
-        self._mm.push(arg)
-    def _pop(self):
-        return self._mm.pop()
-    def has_key(self, key):
-        return self._mm.has_key(key)
+    push = pop = None
+    def _push(self, ob):
+        MultiMapping.push(self, ob)
+    def _pop(self, *args):
+        if args:
+            return apply(MultiMapping.pop, (self,) + args)
+        else:
+            return MultiMapping.pop(self)
     def has_get(self, key):
-        v = self._mm.get(key, self)
-        if v is self:
+        v = self.get(key, _marker)
+        if v is _marker:
             return 0, None
         else:
             return 1, v
@@ -217,6 +221,8 @@
     use to evaluate compiled expressions.
     '''
 
+    _context_class = SafeMapping
+
     def __init__(self, engine, contexts):
         self._engine = engine
         self.contexts = contexts
@@ -226,15 +232,15 @@
         # These contexts will need to be pushed.
         self._current_ctxts = {'local': 1, 'repeat': 1}
         
-        contexts['local'] = lv = SecureMultiMap()
+        contexts['local'] = lv = self._context_class()
         init_local = contexts.get('local', None)
         if init_local:
             lv._push(init_local)
-        contexts['repeat'] = rep =  SecureMultiMap()
+        contexts['repeat'] = rep =  self._context_class()
         contexts['loop'] = rep # alias
         contexts['global'] = gv = contexts.copy()
         gv['standard'] = contexts
-        contexts['var'] = SecureMultiMap(gv, lv)
+        contexts['var'] = self._context_class(gv, lv)
         
     def beginScope(self):
         oldctxts = self._current_ctxts