[pypy-svn] r9045 - in pypy/dist/pypy/interpreter: . test

hpk at codespeak.net hpk at codespeak.net
Thu Feb 10 15:38:56 CET 2005


Author: hpk
Date: Thu Feb 10 15:38:56 2005
New Revision: 9045

Added:
   pypy/dist/pypy/interpreter/test/test_appinterp.py
Modified:
   pypy/dist/pypy/interpreter/baseobjspace.py
Log:
improved exec_with() hack that goes directly
at fast scope and allows for "return" statements
within the applevel code definition. 



Modified: pypy/dist/pypy/interpreter/baseobjspace.py
==============================================================================
--- pypy/dist/pypy/interpreter/baseobjspace.py	(original)
+++ pypy/dist/pypy/interpreter/baseobjspace.py	Thu Feb 10 15:38:56 2005
@@ -277,32 +277,38 @@
         return statement.exec_code(self, w_globals, w_locals)
 
     def exec_with(self, source, **kwargs_w): 
-        """ execute given source at applevel with given name=wrapped value 
-            parameters as its starting scope.  Note: EXPERIMENTAL. 
+        """ return value from executing given source at applevel with 
+            given name=wrapped value parameters as its starting scope.  
+            Note: EXPERIMENTAL. 
         """ 
         space = self
-        pypyco = getpypycode(space, source) 
-
-        # XXX use the fastscope version of Frames? 
+        pypyco,name2index = pypycodecache.getorbuild((space,source), 
+                                                     buildpypycode, kwargs_w) 
         w_glob = space.newdict([])
+        frame = pypyco.create_frame(space, w_glob) 
         for name, w_value in kwargs_w.items(): 
-            space.setitem(w_glob, space.wrap(name), w_value) 
-        pypyco.exec_code(self, w_glob, w_glob) 
-        w_result = space.getitem(w_glob, space.wrap('__return__')) 
-        return w_result 
-
-pypycodecache = {}
-def getpypycode(space, source): 
-    try: 
-        return pypycodecache[(space, source)]
-    except KeyError: 
-        # NOT_RPYTHON  
-        # XXX hack a bit to allow for 'return' statements? 
-        from pypy.interpreter.pycode import PyCode
-        co = compile(source, '', 'exec') 
-        pypyco = PyCode(space)._from_code(co) 
-        pypycodecache[(space, co)] = pypyco 
-        return pypyco 
+            i = name2index[name]  
+            frame.fastlocals_w[i] = w_value 
+        return frame.run() 
+
+pypycodecache = Cache() 
+def buildpypycode((space, source), kwargs_w): 
+    """ NOT_RPYTHON """ 
+    # XXX will change once we have our own compiler 
+    from pypy.interpreter.pycode import PyCode
+    from pypy.tool.pytestsupport import py  # aehem
+    names = kwargs_w.keys() 
+    source = py.code.Source(source) 
+    source = source.putaround("def anon(%s):" % ", ".join(kwargs_w.keys()))
+    d = {}
+    exec source.compile() in d
+    newco = d['anon'].func_code 
+    pypyco = PyCode(space)._from_code(newco) 
+    varnames = list(pypyco.getvarnames())
+    name2index = {}
+    for name, w_value in kwargs_w.items(): 
+        name2index[name] = varnames.index(name)
+    return pypyco, name2index   
 
 ## Table describing the regular part of the interface of object spaces,
 ## namely all methods which only take w_ arguments and return a w_ result

Added: pypy/dist/pypy/interpreter/test/test_appinterp.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/interpreter/test/test_appinterp.py	Thu Feb 10 15:38:56 2005
@@ -0,0 +1,24 @@
+
+import py
+
+def test_execwith_novars(space): 
+    val = space.exec_with("""
+        return 42
+    """) 
+    assert space.eq_w(val, space.wrap(42))
+
+def test_execwith_withvars(space): 
+    val = space.exec_with("""
+        y = 6 * x 
+        return y 
+    """, x = space.wrap(7)) 
+    assert space.eq_w(val, space.wrap(42))
+
+
+def test_execwith_compile_error(space): 
+    excinfo = py.test.raises(SyntaxError, space.exec_with, """
+        y y 
+    """)
+    assert str(excinfo).find('y y') != -1 
+
+    



More information about the Pypy-commit mailing list