Anonymous avatar Anonymous committed b2b1fa1

Implemented exec statement functionality.

Comments (0)

Files changed (3)

pypy/appspace/test/test_exec.py

+"""Test the exec statement functionality.
+
+New for PyPy - Could be incorporated into CPython regression tests.
+"""
+
+import unittest
+
+class TestExecStmt(unittest.TestCase):
+
+    def test_string(self):
+        g = {}
+        l = {}
+        exec "a = 3" in g, l
+        self.failUnlessEqual(l['a'], 3)
+
+    def test_localfill(self):
+        g = {}
+        exec "a = 3" in g
+        self.failUnlessEqual(g['a'], 3)
+        
+    def test_builtinsupply(self):
+        g = {}
+        exec "pass" in g
+        self.failUnless(g.has_key('__builtins__'))
+
+    def test_invalidglobal(self):
+        self.failUnlessRaises(TypeError,"exec 'pass' in 1")
+
+    def test_invalidlocal(self):
+        self.failUnlessRaises(TypeError,"exec 'pass' in {}, 2")
+
+    def test_codeobject(self):
+        co = compile("a = 3", '<string>', 'exec')
+        g = {}
+        l = {}
+        exec co in g, l
+        self.failUnlessEqual(l['a'], 3)
+        
+##    # Commented out as PyPy give errors using open()
+##    #     ["Not availible in restricted mode"]
+##    def test_file(self):
+##        fo = open("test_exec.py", 'r')
+##        g = {}
+##        exec fo in g
+##        self.failUnless(g.has_key('TestExecStmt'))
+        
+    def test_implicit(self):
+        a = 4
+        exec "a = 3"
+        self.failUnlessEqual(a,3)
+
+    def test_tuplelocals(self):
+        g = {}
+        l = {}
+        exec ("a = 3", g, l)
+        self.failUnlessEqual(l['a'], 3)
+        
+    def test_tupleglobals(self):
+        g = {}
+        exec ("a = 3", g)
+        self.failUnlessEqual(g['a'], 3)
+
+    def test_exceptionfallthrough(self):
+        self.failUnlessRaises(TypeError,"exec 'raise TypeError' in {}")
+
+if __name__ == "__main__":
+    unittest.main()

pypy/interpreter/opcode.py

     w_locals  = f.valuestack.pop()
     w_globals = f.valuestack.pop()
     w_prog    = f.valuestack.pop()
-    f.space.gethelper(appfile).call("exec_statement",
+    w_tuple = f.space.gethelper(appfile).call("exec_statement",
                                     [w_prog, w_globals, w_locals,
                                      f.w_builtins, f.w_globals, f.w_locals])
-
+    w_prog = f.space.getitem(w_tuple,f.space.wrap(0))
+    w_globals = f.space.getitem(w_tuple,f.space.wrap(1))
+    w_locals = f.space.getitem(w_tuple,f.space.wrap(2))
+    newframe = pyframe.PyFrame(f.space,f.space.unwrap(w_prog),w_globals,w_locals)
+    ec = f.space.getexecutioncontext()
+    ec.eval_frame(newframe) #discard return value
+    
 def POP_BLOCK(f):
     block = f.blockstack.pop()
     block.cleanup(f)  # the block knows how to clean up the value stack

pypy/interpreter/opcode_app.py

     stream.write(str(x))
     # add a softspace unless we just printed a string which ends in a '\t'
     # or '\n' -- or more generally any whitespace character but ' '
-    if isinstance(x, str) and x[-1].isspace() and x[-1]!=' ':
+    if isinstance(x, str) and len(x) and x[-1].isspace() and x[-1]!=' ':
         return
     # XXX add unicode handling
     file_softspace(stream, True)
                               "for keyword argument '%s'" % key)
         result[key] = value
     return result
+
+def exec_statement(prog, globals, locals,
+                   builtins, caller_globals, caller_locals):
+    """Manipulate parameters to exec statement to (codeobject, dict, dict).
+    """
+    import types
+    if (globals is None and locals is None and
+        isinstance(prog, builtins.tuple) and
+        (len(prog) == 2 or len(prog) == 3)):
+        globals = prog[1]
+        if len(prog) == 3:
+            locals = prog[2]
+        prog = prog[0]
+    if globals is None:
+        globals = caller_globals
+        if locals is None:
+            locals = caller_locals
+    if locals is None:
+        locals = globals
+    if not isinstance(globals, types.DictType):
+        raise TypeError("exec: arg 2 must be a dictionary or None")
+    elif not globals.has_key('__builtins__'):
+        globals['__builtins__'] = builtins
+    if not isinstance(locals, types.DictType):
+        raise TypeError("exec: arg 3 must be a dictionary or None")
+    #HACK to check for code object
+    co = compile('1','<string>','eval')
+    if isinstance(prog, type(co)):
+        return (prog, globals, locals)
+    if not (isinstance(prog, types.StringTypes) or
+            isinstance(prog, types.FileType)):
+        raise TypeError("exec: arg 1 must be a string, file, or code object")
+    if isinstance(prog, types.FileType):
+        flags = 0
+        ## XXX add in parent flag merging
+        co = compile(prog.read(),prog.name,'exec',flags,1)
+        return (co,globals,locals)
+    else: # prog is a string
+        flags = 0
+        ## XXX add in parent flag merging
+        co = compile(prog,'<string>','exec',flags,1)
+        return (co,globals,locals)
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.