[pypy-svn] r73997 - in pypy/branch/cpython-extension/pypy/module/cpyext: . include test

afa at codespeak.net afa at codespeak.net
Thu Apr 22 23:30:30 CEST 2010


Author: afa
Date: Thu Apr 22 23:30:28 2010
New Revision: 73997

Modified:
   pypy/branch/cpython-extension/pypy/module/cpyext/eval.py
   pypy/branch/cpython-extension/pypy/module/cpyext/include/eval.h
   pypy/branch/cpython-extension/pypy/module/cpyext/test/test_eval.py
Log:
Add PyRun_String


Modified: pypy/branch/cpython-extension/pypy/module/cpyext/eval.py
==============================================================================
--- pypy/branch/cpython-extension/pypy/module/cpyext/eval.py	(original)
+++ pypy/branch/cpython-extension/pypy/module/cpyext/eval.py	Thu Apr 22 23:30:28 2010
@@ -1,5 +1,7 @@
-
-from pypy.module.cpyext.api import cpython_api, PyObject, CANNOT_FAIL
+from pypy.interpreter.error import OperationError
+from pypy.rpython.lltypesystem import rffi, lltype
+from pypy.module.cpyext.api import (
+    cpython_api, PyObject, CANNOT_FAIL, CONST_STRING)
 
 @cpython_api([PyObject, PyObject, PyObject], PyObject)
 def PyEval_CallObjectWithKeywords(space, w_obj, w_arg, w_kwds):
@@ -25,3 +27,29 @@
     success, or NULL on failure.  This is the equivalent of the Python expression
     apply(callable_object, args, kw) or callable_object(*args, **kw)."""
     return space.call(w_obj, w_args, w_kw)
+
+# These constants are also defined in include/eval.h
+Py_single_input = 256
+Py_file_input = 257
+Py_eval_input = 258
+
+ at cpython_api([CONST_STRING, rffi.INT_real, PyObject, PyObject], PyObject)
+def PyRun_String(space, str, start, w_globals, w_locals):
+    """This is a simplified interface to PyRun_StringFlags() below, leaving
+    flags set to NULL."""
+    from pypy.module.__builtin__ import compiling
+    w_source = space.wrap(rffi.charp2str(str))
+    filename = "<string>"
+    start = rffi.cast(lltype.Signed, start)
+    if start == Py_file_input:
+        mode = 'exec'
+    elif start == Py_eval_input:
+        mode = 'eval'
+    elif start == Py_single_input:
+        mode = 'single'
+    else:
+        raise OperationError(space.w_ValueError, space.wrap(
+            "invalid mode parameter for PyRun_String"))
+    w_code = compiling.compile(space, w_source, filename, mode)
+    return compiling.eval(space, w_code, w_globals, w_locals)
+

Modified: pypy/branch/cpython-extension/pypy/module/cpyext/include/eval.h
==============================================================================
--- pypy/branch/cpython-extension/pypy/module/cpyext/include/eval.h	(original)
+++ pypy/branch/cpython-extension/pypy/module/cpyext/include/eval.h	Thu Apr 22 23:30:28 2010
@@ -17,6 +17,11 @@
 PyObject * PyObject_CallFunction(PyObject *obj, char *format, ...);
 PyObject * PyObject_CallMethod(PyObject *obj, char *name, char *format, ...);
 
+/* These constants are also defined in cpyext/eval.py */
+#define Py_single_input 256
+#define Py_file_input 257
+#define Py_eval_input 258
+
 #ifdef __cplusplus
 }
 #endif

Modified: pypy/branch/cpython-extension/pypy/module/cpyext/test/test_eval.py
==============================================================================
--- pypy/branch/cpython-extension/pypy/module/cpyext/test/test_eval.py	(original)
+++ pypy/branch/cpython-extension/pypy/module/cpyext/test/test_eval.py	Thu Apr 22 23:30:28 2010
@@ -1,5 +1,7 @@
+from pypy.rpython.lltypesystem import rffi, lltype
 from pypy.module.cpyext.test.test_cpyext import AppTestCpythonExtensionBase
 from pypy.module.cpyext.test.test_api import BaseApiTest
+from pypy.module.cpyext.eval import Py_single_input, Py_file_input, Py_eval_input
 
 class TestEval(BaseApiTest):
     def test_eval(self, space, api):
@@ -56,6 +58,25 @@
         
         assert space.int_w(w_res) == 10
 
+    def test_run_string(self, space, api):
+        def run(code, start, w_globals, w_locals):
+            buf = rffi.str2charp(code)
+            try:
+                return api.PyRun_String(buf, start, w_globals, w_locals)
+            finally:
+                rffi.free_charp(buf)
+
+        w_globals = space.newdict()
+        assert 42 * 43 == space.unwrap(
+            run("42 * 43", Py_eval_input, w_globals, w_globals))
+        assert api.PyObject_Size(w_globals) == 0
+
+        assert run("a = 42 * 43", Py_single_input,
+                   w_globals, w_globals) == space.w_None
+        assert 42 * 43 == space.unwrap(
+            api.PyObject_GetItem(w_globals, space.wrap("a")))
+
+
 class AppTestCall(AppTestCpythonExtensionBase):
     def test_CallFunction(self):
         module = self.import_extension('foo', [



More information about the Pypy-commit mailing list