[Zope-Checkins] CVS: Zope/lib/python/RestrictedPython - RestrictionMutator.py:1.8.8.2

Shane Hathaway shane@digicool.com
Fri, 21 Dec 2001 11:22:16 -0500


Update of /cvs-repository/Zope/lib/python/RestrictedPython
In directory cvs.zope.org:/tmp/cvs-serv28729

Modified Files:
      Tag: RestrictedPython-2_2-branch
	RestrictionMutator.py 
Log Message:
We've been using a strategy of turning expressions into code suites in
order to bind the global names '_getitem_' and '_getattr_' locally, but
this seems brittle somehow.  This new strategy avoids the need to bind
the names locally when in an expression.  Note that the change only
takes effect for the Python 2.2 compiler since RCompile_2_1.py turns
expressions into functions calls.  If you're really following this,
I hope I didn't give you a headache. ;-)


=== Zope/lib/python/RestrictedPython/RestrictionMutator.py 1.8.8.1 => 1.8.8.2 ===
 _print_target_name = ast.Name('_print')
 _getattr_name = ast.Name('_getattr')
+_getattr_name_expr = ast.Name('_getattr_')
 _getitem_name = ast.Name('_getitem')
+_getitem_name_expr = ast.Name('_getitem_')
 _write_guard_name = ast.Name('_write')
 
 # Constants.
@@ -76,9 +78,11 @@
     _getattr_used = 0
     _getitem_used = 0
     _write_used = 0
+    _is_suite = 0  # True for modules and functions, false for expressions
 
 
 class RestrictionMutator:
+
     def __init__(self):
         self.funcinfo = FuncInfo()
         self.warnings = []
@@ -111,6 +115,8 @@
                        'because it starts with "_".' % name)
 
     def prepBody(self, body):
+        """Appends prep code to the beginning of a code suite.
+        """
         info = self.funcinfo
         if info._print_used or info._printed_used:
             # Add code at top for creating _print_target
@@ -136,6 +142,7 @@
 
         former_funcinfo = self.funcinfo
         self.funcinfo = FuncInfo()
+        self.funcinfo._is_suite = 1
         node = walker.defaultVisitNode(node, exclude=('defaults',))
         self.prepBody(node.code.nodes)
         self.funcinfo = former_funcinfo
@@ -187,8 +194,11 @@
             #expr.append(_write_guard_name)
             #self.funcinfo._write_used = 1
         self.funcinfo._getattr_used = 1
-        return ast.CallFunc(_getattr_name,
-                            [node.expr, ast.Const(node.attrname)])
+        if self.funcinfo._is_suite:
+            ga = _getattr_name
+        else:
+            ga = _getattr_name_expr
+        return ast.CallFunc(ga, [node.expr, ast.Const(node.attrname)])
 
     def visitSubscript(self, node, walker):
         node = walker.defaultVisitNode(node)
@@ -221,7 +231,11 @@
                 if upper is None:
                     upper = _None_const
                 subs = ast.Sliceobj([lower, upper])
-            return ast.CallFunc(_getitem_name, [node.expr, subs])
+            if self.funcinfo._is_suite:
+                gi = _getitem_name
+            else:
+                gi = _getitem_name_expr
+            return ast.CallFunc(gi, [node.expr, subs])
         elif node.flags in (OP_DELETE, OP_ASSIGN):
             # set or remove subscript or slice
             node.expr = ast.CallFunc(_write_guard_name, [node.expr])
@@ -249,6 +263,7 @@
         return walker.defaultVisitNode(node)
 
     def visitModule(self, node, walker):
+        self.funcinfo._is_suite = 1
         node = walker.defaultVisitNode(node)
         self.prepBody(node.node.nodes)
         return node