[Checkins] SVN: RestrictedPython/trunk/ Synchronize Zope3's RestrictedPython (which has been set free as an egg) with

Philipp von Weitershausen philikon at philikon.de
Mon Jun 4 13:40:04 EDT 2007


Log message for revision 76322:
  Synchronize Zope3's RestrictedPython (which has been set free as an egg) with
  the actually more evolved RestrictedPython from the Zope 2 tree.
  

Changed:
  U   RestrictedPython/trunk/README.txt
  U   RestrictedPython/trunk/src/RestrictedPython/Eval.py
  U   RestrictedPython/trunk/src/RestrictedPython/Guards.py
  U   RestrictedPython/trunk/src/RestrictedPython/Limits.py
  U   RestrictedPython/trunk/src/RestrictedPython/MutatingWalker.py
  U   RestrictedPython/trunk/src/RestrictedPython/PrintCollector.py
  U   RestrictedPython/trunk/src/RestrictedPython/RCompile.py
  U   RestrictedPython/trunk/src/RestrictedPython/RestrictionMutator.py
  U   RestrictedPython/trunk/src/RestrictedPython/SelectCompiler.py
  U   RestrictedPython/trunk/src/RestrictedPython/Utilities.py
  U   RestrictedPython/trunk/src/RestrictedPython/__init__.py
  A   RestrictedPython/trunk/src/RestrictedPython/notes.txt
  U   RestrictedPython/trunk/src/RestrictedPython/tests/before_and_after.py
  A   RestrictedPython/trunk/src/RestrictedPython/tests/before_and_after24.py
  U   RestrictedPython/trunk/src/RestrictedPython/tests/restricted_module.py
  U   RestrictedPython/trunk/src/RestrictedPython/tests/security_in_syntax.py
  U   RestrictedPython/trunk/src/RestrictedPython/tests/testRestrictions.py
  U   RestrictedPython/trunk/src/RestrictedPython/tests/verify.py

-=-
Modified: RestrictedPython/trunk/README.txt
===================================================================
--- RestrictedPython/trunk/README.txt	2007-06-04 16:57:20 UTC (rev 76321)
+++ RestrictedPython/trunk/README.txt	2007-06-04 17:40:03 UTC (rev 76322)
@@ -8,6 +8,14 @@
 ********
 
 ==================
+3.4.0 (2007/06/04)
+==================
+
+- RestrictedPython now has its own release cycle as a separate egg.
+
+- Synchronized with RestrictedPython from Zope 2 tree.
+
+==================
 3.2.0 (2006/01/05)
 ==================
 

Modified: RestrictedPython/trunk/src/RestrictedPython/Eval.py
===================================================================
--- RestrictedPython/trunk/src/RestrictedPython/Eval.py	2007-06-04 16:57:20 UTC (rev 76321)
+++ RestrictedPython/trunk/src/RestrictedPython/Eval.py	2007-06-04 17:40:03 UTC (rev 76322)
@@ -1,9 +1,9 @@
 ##############################################################################
 #
-# Copyright (c) 2001 Zope Corporation and Contributors. All Rights Reserved.
+# Copyright (c) 2002 Zope Corporation and Contributors. All Rights Reserved.
 #
 # This software is subject to the provisions of the Zope Public License,
-# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
+# 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

Modified: RestrictedPython/trunk/src/RestrictedPython/Guards.py
===================================================================
--- RestrictedPython/trunk/src/RestrictedPython/Guards.py	2007-06-04 16:57:20 UTC (rev 76321)
+++ RestrictedPython/trunk/src/RestrictedPython/Guards.py	2007-06-04 17:40:03 UTC (rev 76322)
@@ -1,9 +1,9 @@
 ##############################################################################
 #
-# Copyright (c) 2001 Zope Corporation and Contributors. All Rights Reserved.
+# Copyright (c) 2002 Zope Corporation and Contributors. All Rights Reserved.
 #
 # This software is subject to the provisions of the Zope Public License,
-# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
+# 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

Modified: RestrictedPython/trunk/src/RestrictedPython/Limits.py
===================================================================
--- RestrictedPython/trunk/src/RestrictedPython/Limits.py	2007-06-04 16:57:20 UTC (rev 76321)
+++ RestrictedPython/trunk/src/RestrictedPython/Limits.py	2007-06-04 17:40:03 UTC (rev 76322)
@@ -1,9 +1,9 @@
 ##############################################################################
 #
-# Copyright (c) 2001 Zope Corporation and Contributors. All Rights Reserved.
+# Copyright (c) 2002 Zope Corporation and Contributors. All Rights Reserved.
 #
 # This software is subject to the provisions of the Zope Public License,
-# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
+# 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

Modified: RestrictedPython/trunk/src/RestrictedPython/MutatingWalker.py
===================================================================
--- RestrictedPython/trunk/src/RestrictedPython/MutatingWalker.py	2007-06-04 16:57:20 UTC (rev 76321)
+++ RestrictedPython/trunk/src/RestrictedPython/MutatingWalker.py	2007-06-04 17:40:03 UTC (rev 76322)
@@ -1,9 +1,9 @@
 ##############################################################################
 #
-# Copyright (c) 2001 Zope Corporation and Contributors. All Rights Reserved.
+# Copyright (c) 2002 Zope Corporation and Contributors. All Rights Reserved.
 #
 # This software is subject to the provisions of the Zope Public License,
-# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
+# 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

Modified: RestrictedPython/trunk/src/RestrictedPython/PrintCollector.py
===================================================================
--- RestrictedPython/trunk/src/RestrictedPython/PrintCollector.py	2007-06-04 16:57:20 UTC (rev 76321)
+++ RestrictedPython/trunk/src/RestrictedPython/PrintCollector.py	2007-06-04 17:40:03 UTC (rev 76322)
@@ -1,9 +1,9 @@
 ##############################################################################
 #
-# Copyright (c) 2001 Zope Corporation and Contributors. All Rights Reserved.
+# Copyright (c) 2002 Zope Corporation and Contributors. All Rights Reserved.
 #
 # This software is subject to the provisions of the Zope Public License,
-# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
+# 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

Modified: RestrictedPython/trunk/src/RestrictedPython/RCompile.py
===================================================================
--- RestrictedPython/trunk/src/RestrictedPython/RCompile.py	2007-06-04 16:57:20 UTC (rev 76321)
+++ RestrictedPython/trunk/src/RestrictedPython/RCompile.py	2007-06-04 17:40:03 UTC (rev 76322)
@@ -1,9 +1,9 @@
 ##############################################################################
 #
-# Copyright (c) 2001 Zope Corporation and Contributors. All Rights Reserved.
+# Copyright (c) 2002 Zope Corporation and Contributors. All Rights Reserved.
 #
 # This software is subject to the provisions of the Zope Public License,
-# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
+# 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
@@ -46,6 +46,8 @@
     # See concrete subclasses below.
 
     def __init__(self, source, filename):
+        if source:
+            source = '\n'.join(source.splitlines())
         self.rm = RestrictionMutator()
         AbstractCompileMode.__init__(self, source, filename)
 
@@ -210,6 +212,8 @@
 
     def __init__(self, p, body, name, filename, globals):
         self.params = p
+        if body:
+            body = '\n'.join(body.splitlines())
         self.body = body
         self.name = name
         self.globals = globals or []
@@ -224,12 +228,13 @@
         # Stitch the body code into the function.
         f.code.nodes = body_code.node.nodes
         f.name = self.name
-        # Look for a docstring.
-        stmt1 = f.code.nodes[0]
-        if (isinstance(stmt1, ast.Discard) and
-            isinstance(stmt1.expr, ast.Const) and
-            isinstance(stmt1.expr.value, str)):
-            f.doc = stmt1.expr.value
+        # Look for a docstring, if there are any nodes at all
+        if len(f.code.nodes) > 0:
+            stmt1 = f.code.nodes[0]
+            if (isinstance(stmt1, ast.Discard) and
+                isinstance(stmt1.expr, ast.Const) and
+                isinstance(stmt1.expr.value, str)):
+                f.doc = stmt1.expr.value
         # The caller may specify that certain variables are globals
         # so that they can be referenced before a local assignment.
         # The only known example is the variables context, container,

Modified: RestrictedPython/trunk/src/RestrictedPython/RestrictionMutator.py
===================================================================
--- RestrictedPython/trunk/src/RestrictedPython/RestrictionMutator.py	2007-06-04 16:57:20 UTC (rev 76321)
+++ RestrictedPython/trunk/src/RestrictedPython/RestrictionMutator.py	2007-06-04 17:40:03 UTC (rev 76322)
@@ -1,9 +1,9 @@
 ##############################################################################
 #
-# Copyright (c) 2001 Zope Corporation and Contributors. All Rights Reserved.
+# Copyright (c) 2002 Zope Corporation and Contributors. All Rights Reserved.
 #
 # This software is subject to the provisions of the Zope Public License,
-# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
+# 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
@@ -47,6 +47,7 @@
 _getiter_name = ast.Name("_getiter_")
 _print_target_name = ast.Name("_print")
 _write_name = ast.Name("_write_")
+_inplacevar_name = ast.Name("_inplacevar_")
 
 # Constants.
 _None_const = ast.Const(None)
@@ -94,6 +95,9 @@
             # Note: "_" *is* allowed.
             self.error(node, '"%s" is an invalid variable name because'
                        ' it starts with "_"' % name)
+        if name.endswith('__roles__'):
+            self.error(node, '"%s" is an invalid variable name because '
+                       'it ends with "__roles__".' % name)
         if name == "printed":
             self.error(node, '"printed" is a reserved name.')
 
@@ -109,6 +113,9 @@
             # Note: "_" *is* allowed.
             self.error(node, '"%s" is an invalid attribute name '
                        'because it starts with "_".' % name)
+        if name.endswith('__roles__'):
+            self.error(node, '"%s" is an invalid attribute name '
+                       'because it ends with "__roles__".' % name)
 
     def prepBody(self, body):
         """Insert code for print at the beginning of the code suite."""
@@ -233,9 +240,9 @@
         #   for x in expr:
         # to
         #   for x in _getiter(expr):
+        #        # Note that visitListCompFor is the same thing.
         #
-        # Note that visitListCompFor is the same thing.  Exactly the same
-        # transformation is needed to convert
+        # Also for list comprehensions:
         #   [... for x in expr ...]
         # to
         #   [... for x in _getiter(expr) ...]
@@ -245,6 +252,15 @@
 
     visitListCompFor = visitFor
 
+    def visitGenExprFor(self, node, walker):
+        # convert
+        #   (... for x in expr ...)
+        # to
+        #   (... for x in _getiter(expr) ...)
+        node = walker.defaultVisitNode(node)
+        node.iter = ast.CallFunc(_getiter_name, [node.iter])
+        return node
+
     def visitGetattr(self, node, walker):
         """Converts attribute access to a function call.
 
@@ -359,8 +375,23 @@
         This could be a problem if untrusted code got access to a
         mutable database object that supports augmented assignment.
         """
-        node.node.in_aug_assign = True
-        return walker.defaultVisitNode(node)
+        if node.node.__class__.__name__ == 'Name':
+            node = walker.defaultVisitNode(node)
+            newnode = ast.Assign(
+                [ast.AssName(node.node.name, OP_ASSIGN)],
+                ast.CallFunc(
+                    _inplacevar_name,
+                    [ast.Const(node.op),
+                     ast.Name(node.node.name),
+                     node.expr,
+                     ]
+                    ),
+                )
+            newnode.lineno = node.lineno
+            return newnode
+        else:
+            node.node.in_aug_assign = True
+            return walker.defaultVisitNode(node)
 
     def visitImport(self, node, walker):
         """Checks names imported using checkName()."""

Modified: RestrictedPython/trunk/src/RestrictedPython/SelectCompiler.py
===================================================================
--- RestrictedPython/trunk/src/RestrictedPython/SelectCompiler.py	2007-06-04 16:57:20 UTC (rev 76321)
+++ RestrictedPython/trunk/src/RestrictedPython/SelectCompiler.py	2007-06-04 17:40:03 UTC (rev 76322)
@@ -1,9 +1,9 @@
 ##############################################################################
 #
-# Copyright (c) 2001 Zope Corporation and Contributors. All Rights Reserved.
+# Copyright (c) 2002 Zope Corporation and Contributors. All Rights Reserved.
 #
 # This software is subject to the provisions of the Zope Public License,
-# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
+# 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

Modified: RestrictedPython/trunk/src/RestrictedPython/Utilities.py
===================================================================
--- RestrictedPython/trunk/src/RestrictedPython/Utilities.py	2007-06-04 16:57:20 UTC (rev 76321)
+++ RestrictedPython/trunk/src/RestrictedPython/Utilities.py	2007-06-04 17:40:03 UTC (rev 76322)
@@ -1,9 +1,9 @@
 ##############################################################################
 #
-# Copyright (c) 2001 Zope Corporation and Contributors. All Rights Reserved.
+# Copyright (c) 2002 Zope Corporation and Contributors. All Rights Reserved.
 #
 # This software is subject to the provisions of the Zope Public License,
-# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
+# 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
@@ -13,8 +13,7 @@
 
 __version__='$Revision: 1.7 $'[11:-2]
 
-import string, math, random
-import DocumentTemplate.sequence
+import string, math, random, sets
 
 utility_builtins = {}
 
@@ -22,13 +21,21 @@
 utility_builtins['math'] = math
 utility_builtins['random'] = random
 utility_builtins['whrandom'] = random
-utility_builtins['sequence'] = DocumentTemplate.sequence
+utility_builtins['sets'] = sets
 
 try:
     import DateTime
     utility_builtins['DateTime']= DateTime.DateTime
-except: pass
+except ImportError:
+    pass
 
+try:
+    import DocumentTemplate.sequence
+    utility_builtins['sequence']= DocumentTemplate.sequence
+except ImportError:
+    pass
+
+
 def same_type(arg1, *args):
     '''Compares the class or type of two or more objects.'''
     t = getattr(arg1, '__class__', type(arg1))

Modified: RestrictedPython/trunk/src/RestrictedPython/__init__.py
===================================================================
--- RestrictedPython/trunk/src/RestrictedPython/__init__.py	2007-06-04 16:57:20 UTC (rev 76321)
+++ RestrictedPython/trunk/src/RestrictedPython/__init__.py	2007-06-04 17:40:03 UTC (rev 76322)
@@ -1,9 +1,9 @@
 ##############################################################################
 #
-# Copyright (c) 2001 Zope Corporation and Contributors. All Rights Reserved.
+# Copyright (c) 2002 Zope Corporation and Contributors. All Rights Reserved.
 #
 # This software is subject to the provisions of the Zope Public License,
-# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
+# 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

Copied: RestrictedPython/trunk/src/RestrictedPython/notes.txt (from rev 76321, Zope/trunk/lib/python/RestrictedPython/notes.txt)
===================================================================
--- RestrictedPython/trunk/src/RestrictedPython/notes.txt	                        (rev 0)
+++ RestrictedPython/trunk/src/RestrictedPython/notes.txt	2007-06-04 17:40:03 UTC (rev 76322)
@@ -0,0 +1,95 @@
+How it works
+============
+
+Every time I see this code, I have to relearn it.  These notes will
+hopefully make this a little easier. :)
+
+- The important module is RCompile.  The entry points are the
+  compile_restricted_* functions.
+
+  + compile_restricted_function is used by Python scripts.
+
+  + compile_restricted_eval is used by ZPT
+
+    and by DTML indirectly through Eval.RestrictionCapableEval.
+
+- OK, so lets see how this works by following the logic of
+  compile_restricted_eval. 
+
+  - First, we create an RExpression, passing the source and a 
+    "file name", to be used in tracebacks.
+
+    Now, an RExpression is just:
+
+    + a subclass of RestrictedCompileMode and Expression.
+
+      Expression is a subclass of AbstractCompileMode that sets it's
+      mode to 'eval' and everided compile. Sigh.
+
+    + RestrictedCompileMode is a subclass of AbstractCompileMode
+      that changes a bunch of things. :)  These include compile, so we 
+      can ignore the compile we got from Expression.  It would have
+      been simpler to just set the dang mode in RExpression. Sigh.
+
+      RestrictedCompileMode seem to be the interestng base class. I
+      assume it implements the interesting functionality. We'll see
+      below...
+
+  - Next, we call compileAndTuplize.
+
+    + This calls compile on the RExpression.  It has an error
+      handler that does something that I hope I don't care about. :)
+
+    + It then calls the genCode method on the RExpression.  This is
+      boring, so we'll not worry about it.
+
+  - The compile method provided by RestrictedCompileMode is
+    interesting. 
+
+    + First it calls _get_tree.
+
+      * It uses compiler.parse to parse the source
+
+      * it uses MutatingWalker.walk to mutaate the tree using the
+        RestrictedCompileMode's 'rm' attr, which is a
+        RestrictionMutator.
+
+        The RestrictionMutator has the recipies for mutating the parse
+        tree.  (Note, for comparison, that Zope3's
+        zope.security.untrustedpython.rcompile module an alternative
+        RestrictionMutator that provides a much smaller set of
+        changes.)  
+
+        A mutator has visit method for different kinds of AST
+        nodes. These visit methods may mutate nodes or return new
+        nodes that replace the originally visited nodes.  There is a
+        default visitor that visits a node's children and replaces the
+        children who's visitors returned new nodes.
+
+        The walk function just calls the visitor for the root node of
+        the given tree.  Note _get_tree ignores the walk return value,
+        thus assuming that the visitor for the root node doesn't
+        return a new node.  This is a theoretical bug that we can
+        ignore. 
+
+    + Second, it generates the code. This too is boring. 
+
+- So this seems simple enough. ;)  When we want to add a check, we
+  need to update or add a visit function in RestrictionMutator.
+
+  How does a visit function work.
+
+  - First, we usually call walker.defaultVisitNode(node). This
+    transforms the node's child nodes.  
+
+  - Then we hack the node, or possibly return the node. To do this, we
+    have to know how the node works.
+
+  - The hack often involved changing the code to call some checker
+    function. These have names like _name_.  These are names that
+    would be illegal in the input source.
+
+    If this is a new function, we have to provide it in
+    AccessControl.ZopeGuards._safe_globals.
+
+- Don't forget to add a test case to tests.before_and_after.

Modified: RestrictedPython/trunk/src/RestrictedPython/tests/before_and_after.py
===================================================================
--- RestrictedPython/trunk/src/RestrictedPython/tests/before_and_after.py	2007-06-04 16:57:20 UTC (rev 76321)
+++ RestrictedPython/trunk/src/RestrictedPython/tests/before_and_after.py	2007-06-04 17:40:03 UTC (rev 76322)
@@ -4,7 +4,7 @@
 # All Rights Reserved.
 #
 # This software is subject to the provisions of the Zope Public License,
-# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
+# 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
@@ -75,7 +75,7 @@
 def nested_list_comprehension_after():
     x = [x**2 + y**2 for x in _getiter_(whatever1) if x >= 0
                      for y in _getiter_(whatever2) if y >= x]
-
+    
 # print
 
 def simple_print_before():
@@ -244,3 +244,18 @@
 
 def lambda_with_getattr_in_defaults_after():
     f = lambda x=_getattr_(y, "z"): x
+
+
+# augmented operators
+# Note that we don't have to worry about item, attr, or slice assignment,
+# as they are disallowed. Yay!
+
+## def inplace_id_add_before():
+##     x += y+z
+
+## def inplace_id_add_after():
+##     x = _inplacevar_('+=', x, y+z)
+
+
+
+    

Copied: RestrictedPython/trunk/src/RestrictedPython/tests/before_and_after24.py (from rev 76321, Zope/trunk/lib/python/RestrictedPython/tests/before_and_after24.py)
===================================================================
--- RestrictedPython/trunk/src/RestrictedPython/tests/before_and_after24.py	                        (rev 0)
+++ RestrictedPython/trunk/src/RestrictedPython/tests/before_and_after24.py	2007-06-04 17:40:03 UTC (rev 76322)
@@ -0,0 +1,41 @@
+##############################################################################
+#
+# Copyright (c) 2003 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.
+#
+##############################################################################
+"""Restricted Python transformation examples
+
+This module contains pairs of functions. Each pair has a before and an
+after function.  The after function shows the source code equivalent
+of the before function after it has been modified by the restricted
+compiler.
+
+These examples are actually used in the testRestrictions.py
+checkBeforeAndAfter() unit tests, which verifies that the restricted compiler
+actually produces the same output as would be output by the normal compiler
+for the after function.
+
+$Id$
+"""
+
+def simple_generator_expression_before():
+    x = (y**2 for y in whatever if y > 3)
+
+def simple_generator_expression_after():
+    x = (y**2 for y in _getiter_(whatever) if y > 3)
+
+def nested_generator_expression_before():
+    x = (x**2 + y**2 for x in whatever1 if x >= 0
+                     for y in whatever2 if y >= x)
+
+def nested_generator_expression_after():
+    x = (x**2 + y**2 for x in _getiter_(whatever1) if x >= 0
+                     for y in _getiter_(whatever2) if y >= x)

Modified: RestrictedPython/trunk/src/RestrictedPython/tests/restricted_module.py
===================================================================
--- RestrictedPython/trunk/src/RestrictedPython/tests/restricted_module.py	2007-06-04 16:57:20 UTC (rev 76321)
+++ RestrictedPython/trunk/src/RestrictedPython/tests/restricted_module.py	2007-06-04 17:40:03 UTC (rev 76322)
@@ -40,6 +40,10 @@
     print f(*(300, 20), **{'z': 1}),
     return printed
 
+def try_inplace():
+    x = 1
+    x += 3
+
 def primes():
     # Somewhat obfuscated code on purpose
     print filter(None,map(lambda y:y*reduce(lambda x,y:x*y!=0,

Modified: RestrictedPython/trunk/src/RestrictedPython/tests/security_in_syntax.py
===================================================================
--- RestrictedPython/trunk/src/RestrictedPython/tests/security_in_syntax.py	2007-06-04 16:57:20 UTC (rev 76321)
+++ RestrictedPython/trunk/src/RestrictedPython/tests/security_in_syntax.py	2007-06-04 17:40:03 UTC (rev 76322)
@@ -54,3 +54,16 @@
 def keyword_arg_with_bad_name():
     def f(okname=1, __badname=2):
         pass
+
+def no_augmeneted_assignment_to_sub():
+    a[b] += c
+
+def no_augmeneted_assignment_to_attr():
+    a.b += c
+
+def no_augmeneted_assignment_to_slice():
+    a[x:y] += c
+
+def no_augmeneted_assignment_to_slice2():
+    a[x:y:z] += c
+

Modified: RestrictedPython/trunk/src/RestrictedPython/tests/testRestrictions.py
===================================================================
--- RestrictedPython/trunk/src/RestrictedPython/tests/testRestrictions.py	2007-06-04 16:57:20 UTC (rev 76321)
+++ RestrictedPython/trunk/src/RestrictedPython/tests/testRestrictions.py	2007-06-04 17:40:03 UTC (rev 76322)
@@ -12,8 +12,8 @@
 
 from RestrictedPython import compile_restricted, PrintCollector
 from RestrictedPython.Eval import RestrictionCapableEval
-from RestrictedPython.tests import before_and_after, restricted_module, verify
-from RestrictedPython.RCompile import RModule
+from RestrictedPython.tests import restricted_module, verify
+from RestrictedPython.RCompile import RModule, RFunction
 
 try:
     __file__
@@ -51,8 +51,13 @@
     return fn, msg
 
 def get_source(func):
-    """Less silly interface to find_source""" # Sheesh
-    return find_source(func.func_globals['__file__'], func.func_code)[1]
+    """Less silly interface to find_source"""
+    file = func.func_globals['__file__']
+    if file.endswith('.pyc'):
+        file = file[:-1]
+    source = find_source(file, func.func_code)[1]
+    assert source.strip(), "Source should not be empty!"
+    return source
 
 def create_rmodule():
     global rmodule
@@ -175,6 +180,14 @@
     apply_wrapper_called.append('yes')
     return func(*args, **kws)
 
+inplacevar_wrapper_called = {}
+def inplacevar_wrapper(op, x, y):
+    inplacevar_wrapper_called[op] = x, y
+    # This is really lame.  But it's just a test. :)
+    globs = {'x': x, 'y': y}
+    exec 'x'+op+'y' in globs
+    return globs['x']
+
 class RestrictionTests(unittest.TestCase):
     def execFunc(self, name, *args, **kw):
         func = rmodule[name]
@@ -191,6 +204,7 @@
         # work for everything.
                                   '_getiter_': list,
                                   '_apply_': apply_wrapper,
+                                  '_inplacevar_': inplacevar_wrapper,
                                   })
         return func(*args, **kw)
 
@@ -243,6 +257,11 @@
         self.assertEqual(apply_wrapper_called, ["yes"])
         self.assertEqual(res, "321")
 
+    def checkInplace(self):
+        inplacevar_wrapper_called.clear()
+        res = self.execFunc('try_inplace')
+        self.assertEqual(inplacevar_wrapper_called['+='], (1, 3))
+
     def checkDenied(self):
         for k in rmodule.keys():
             if k[:6] == 'denied':
@@ -314,7 +333,7 @@
 
     def checkBeforeAndAfter(self):
         from RestrictedPython.RCompile import RModule
-
+        from RestrictedPython.tests import before_and_after
         from compiler import parse
 
         defre = re.compile(r'def ([_A-Za-z0-9]+)_(after|before)\(')
@@ -339,6 +358,34 @@
             rm.compile()
             verify.verify(rm.getCode())
 
+    if sys.version_info[:2] >= (2, 4):
+        def checkBeforeAndAfter24(self):
+            from RestrictedPython.RCompile import RModule
+            from RestrictedPython.tests import before_and_after24
+            from compiler import parse
+
+            defre = re.compile(r'def ([_A-Za-z0-9]+)_(after|before)\(')
+
+            beforel = [name for name in before_and_after24.__dict__
+                       if name.endswith("_before")]
+
+            for name in beforel:
+                before = getattr(before_and_after24, name)
+                before_src = get_source(before)
+                before_src = re.sub(defre, r'def \1(', before_src)
+                rm = RModule(before_src, '')
+                tree_before = rm._get_tree()
+
+                after = getattr(before_and_after24, name[:-6]+'after')
+                after_src = get_source(after)
+                after_src = re.sub(defre, r'def \1(', after_src)
+                tree_after = parse(after_src)
+
+                self.assertEqual(str(tree_before), str(tree_after))
+
+                rm.compile()
+                verify.verify(rm.getCode())
+
     def _compile_file(self, name):
         path = os.path.join(_HERE, name)
         f = open(path, "r")
@@ -355,7 +402,7 @@
         def getiter(seq):
             calls.append(seq)
             return list(seq)
-        globals = {"_getiter_": getiter}
+        globals = {"_getiter_": getiter, '_inplacevar_': inplacevar_wrapper}
         exec co in globals, {}
         # The comparison here depends on the exact code that is
         # contained in unpack.py.
@@ -437,6 +484,12 @@
         co = self._compile_file("lambda.py")
         exec co in {}, {}
 
+    def checkEmpty(self):
+        rf = RFunction("", "", "issue945", "empty.py", {})
+        rf.parse()
+        rf2 = RFunction("", "# still empty\n\n# by", "issue945", "empty.py", {})
+        rf2.parse()
+
     def checkSyntaxError(self):
         err = ("def f(x, y):\n"
                "    if x, y < 2 + 1:\n"
@@ -446,9 +499,37 @@
         self.assertRaises(SyntaxError,
                           compile_restricted, err, "<string>", "exec")
 
+    # these two tests check that source code with Windows line
+    # endings still works.
+
+    def checkLineEndingsRFunction(self):
+        from RestrictedPython.RCompile import RFunction
+        gen = RFunction(
+            p='',
+            body='# testing\r\nprint "testing"\r\nreturn printed\n',
+            name='test',
+            filename='<test>',
+            globals=(),
+            )
+        gen.mode = 'exec'
+        # if the source has any line ending other than \n by the time
+        # parse() is called, then you'll get a syntax error.
+        gen.parse()
+
+    def checkLineEndingsRestrictedCompileMode(self):
+        from RestrictedPython.RCompile import RestrictedCompileMode
+        gen = RestrictedCompileMode(
+            '# testing\r\nprint "testing"\r\nreturn printed\n',
+            '<testing>'
+            )
+        gen.mode='exec'
+        # if the source has any line ending other than \n by the time
+        # parse() is called, then you'll get a syntax error.
+        gen.parse()
+
+        
 create_rmodule()
 
-
 def test_suite():
     return unittest.makeSuite(RestrictionTests, 'check')
 

Modified: RestrictedPython/trunk/src/RestrictedPython/tests/verify.py
===================================================================
--- RestrictedPython/trunk/src/RestrictedPython/tests/verify.py	2007-06-04 16:57:20 UTC (rev 76321)
+++ RestrictedPython/trunk/src/RestrictedPython/tests/verify.py	2007-06-04 17:40:03 UTC (rev 76322)
@@ -3,7 +3,7 @@
 # Copyright (c) 2003 Zope Corporation and Contributors. All Rights Reserved.
 #
 # This software is subject to the provisions of the Zope Public License,
-# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
+# 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



More information about the Checkins mailing list