[pypy-commit] pypy default: cpyext: implement PyRun_StringFlags()
amauryfa
noreply at buildbot.pypy.org
Thu Feb 23 21:19:55 CET 2012
Author: Amaury Forgeot d'Arc <amauryfa at gmail.com>
Branch:
Changeset: r52821:91960d426061
Date: 2012-02-23 01:37 +0100
http://bitbucket.org/pypy/pypy/changeset/91960d426061/
Log: cpyext: implement PyRun_StringFlags()
diff --git a/pypy/module/cpyext/eval.py b/pypy/module/cpyext/eval.py
--- a/pypy/module/cpyext/eval.py
+++ b/pypy/module/cpyext/eval.py
@@ -9,7 +9,7 @@
from pypy.module.__builtin__ import compiling
PyCompilerFlags = cpython_struct(
- "PyCompilerFlags", ())
+ "PyCompilerFlags", (("cf_flags", rffi.INT),))
PyCompilerFlagsPtr = lltype.Ptr(PyCompilerFlags)
@cpython_api([PyObject, PyObject, PyObject], PyObject)
@@ -86,7 +86,7 @@
Py_file_input = 257
Py_eval_input = 258
-def compile_string(space, source, filename, start):
+def compile_string(space, source, filename, start, flags=0):
w_source = space.wrap(source)
start = rffi.cast(lltype.Signed, start)
if start == Py_file_input:
@@ -98,7 +98,7 @@
else:
raise OperationError(space.w_ValueError, space.wrap(
"invalid mode parameter for compilation"))
- return compiling.compile(space, w_source, filename, mode)
+ return compiling.compile(space, w_source, filename, mode, flags)
def run_string(space, source, filename, start, w_globals, w_locals):
w_code = compile_string(space, source, filename, start)
@@ -121,6 +121,23 @@
filename = "<string>"
return run_string(space, source, filename, start, w_globals, w_locals)
+ at cpython_api([rffi.CCHARP, rffi.INT_real, PyObject, PyObject,
+ PyCompilerFlagsPtr], PyObject)
+def PyRun_StringFlags(space, source, start, w_globals, w_locals, flagsptr):
+ """Execute Python source code from str in the context specified by the
+ dictionaries globals and locals with the compiler flags specified by
+ flags. The parameter start specifies the start token that should be used to
+ parse the source code.
+
+ Returns the result of executing the code as a Python object, or NULL if an
+ exception was raised."""
+ if flagsptr:
+ flags = flagsptr.c_cf_flags
+ else:
+ flags = 0
+ w_code = compile_string(space, source, "<string>", start, flags)
+ return compiling.eval(space, w_code, w_globals, w_locals)
+
@cpython_api([FILEP, CONST_STRING, rffi.INT_real, PyObject, PyObject], PyObject)
def PyRun_File(space, fp, filename, start, w_globals, w_locals):
"""This is a simplified interface to PyRun_FileExFlags() below, leaving
@@ -162,7 +179,7 @@
@cpython_api([rffi.CCHARP, rffi.CCHARP, rffi.INT_real, PyCompilerFlagsPtr],
PyObject)
-def Py_CompileStringFlags(space, source, filename, start, flags):
+def Py_CompileStringFlags(space, source, filename, start, flagsptr):
"""Parse and compile the Python source code in str, returning the
resulting code object. The start token is given by start; this
can be used to constrain the code which can be compiled and should
@@ -172,7 +189,8 @@
returns NULL if the code cannot be parsed or compiled."""
source = rffi.charp2str(source)
filename = rffi.charp2str(filename)
- if flags:
- raise OperationError(space.w_NotImplementedError, space.wrap(
- "cpyext Py_CompileStringFlags does not accept flags"))
- return compile_string(space, source, filename, start)
+ if flagsptr:
+ flags = flagsptr.c_cf_flags
+ else:
+ flags = 0
+ return compile_string(space, source, filename, start, flags)
diff --git a/pypy/module/cpyext/include/pythonrun.h b/pypy/module/cpyext/include/pythonrun.h
--- a/pypy/module/cpyext/include/pythonrun.h
+++ b/pypy/module/cpyext/include/pythonrun.h
@@ -19,6 +19,8 @@
int cf_flags; /* bitmask of CO_xxx flags relevant to future */
} PyCompilerFlags;
+#define PyCF_SOURCE_IS_UTF8 0x0100
+
#define Py_CompileString(str, filename, start) Py_CompileStringFlags(str, filename, start, NULL)
#ifdef __cplusplus
diff --git a/pypy/module/cpyext/stubs.py b/pypy/module/cpyext/stubs.py
--- a/pypy/module/cpyext/stubs.py
+++ b/pypy/module/cpyext/stubs.py
@@ -2483,17 +2483,6 @@
source code is read from fp instead of an in-memory string."""
raise NotImplementedError
- at cpython_api([rffi.CCHARP, rffi.INT_real, PyObject, PyObject, PyCompilerFlags], PyObject)
-def PyRun_StringFlags(space, str, start, globals, locals, flags):
- """Execute Python source code from str in the context specified by the
- dictionaries globals and locals with the compiler flags specified by
- flags. The parameter start specifies the start token that should be used to
- parse the source code.
-
- Returns the result of executing the code as a Python object, or NULL if an
- exception was raised."""
- raise NotImplementedError
-
@cpython_api([FILE, rffi.CCHARP, rffi.INT_real, PyObject, PyObject, rffi.INT_real], PyObject)
def PyRun_FileEx(space, fp, filename, start, globals, locals, closeit):
"""This is a simplified interface to PyRun_FileExFlags() below, leaving
diff --git a/pypy/module/cpyext/test/test_eval.py b/pypy/module/cpyext/test/test_eval.py
--- a/pypy/module/cpyext/test/test_eval.py
+++ b/pypy/module/cpyext/test/test_eval.py
@@ -2,9 +2,10 @@
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)
+ Py_single_input, Py_file_input, Py_eval_input, PyCompilerFlags)
from pypy.module.cpyext.api import fopen, fclose, fileno, Py_ssize_tP
from pypy.interpreter.gateway import interp2app
+from pypy.interpreter.astcompiler import consts
from pypy.tool.udir import udir
import sys, os
@@ -112,6 +113,16 @@
assert 42 * 43 == space.unwrap(
api.PyObject_GetItem(w_globals, space.wrap("a")))
+ def test_run_string_flags(self, space, api):
+ flags = lltype.malloc(PyCompilerFlags, flavor='raw')
+ flags.c_cf_flags = rffi.cast(rffi.INT, consts.PyCF_SOURCE_IS_UTF8)
+ w_globals = space.newdict()
+ api.PyRun_StringFlags("a = u'caf\xc3\xa9'", Py_single_input,
+ w_globals, w_globals, flags)
+ w_a = space.getitem(w_globals, space.wrap("a"))
+ assert space.unwrap(w_a) == u'caf\xe9'
+ lltype.free(flags, flavor='raw')
+
def test_run_file(self, space, api):
filepath = udir / "cpyext_test_runfile.py"
filepath.write("raise ZeroDivisionError")
More information about the pypy-commit
mailing list