From 5bb27ff1ed3f114fed8aba0123e933ea06987bcd Mon Sep 17 00:00:00 2001 From: Andrey Plotnikov Date: Wed, 19 Aug 2009 14:48:24 +0800 Subject: [PATCH] code object support in exec statement --- Cython/Compiler/Builtin.py | 47 ++++++++++++++++++++++---------------- 1 file changed, 27 insertions(+), 20 deletions(-) diff --git a/Cython/Compiler/Builtin.py b/Cython/Compiler/Builtin.py index 57028e67..5f85810a 100644 --- a/Cython/Compiler/Builtin.py +++ b/Cython/Compiler/Builtin.py @@ -182,27 +182,34 @@ static PyObject* __Pyx_PyRun(PyObject* o, PyObject* globals, PyObject* locals) { globals = locals; } - if (PyUnicode_Check(o)) { - s = PyUnicode_AsUTF8String(o); - if (!s) goto bad; - o = s; - #if PY_MAJOR_VERSION >= 3 - } else if (!PyBytes_Check(o)) { - #else - } else if (!PyString_Check(o)) { - #endif - /* FIXME: support file objects and code objects */ - PyErr_SetString(PyExc_TypeError, - "exec currently requires a string as code input."); - goto bad; + if (PyDict_GetItemString(globals, "__builtins__") == NULL) { + PyDict_SetItemString(globals, "__builtins__", PyEval_GetBuiltins()); + } + + if (PyCode_Check(o)) { + result = PyEval_EvalCode((PyCodeObject *)o, globals, locals); + } + else { + if (PyUnicode_Check(o)) { + s = PyUnicode_AsUTF8String(o); + if (!s) goto bad; + o = s; + #if PY_MAJOR_VERSION >= 3 + } else if (!PyBytes_Check(o)) { + #else + } else if (!PyString_Check(o)) { + #endif + PyErr_SetString(PyExc_TypeError, + "exec: arg 1 must be string, bytes or code object"); + goto bad; + } + #if PY_MAJOR_VERSION >= 3 + code = PyBytes_AS_STRING(o); + #else + code = PyString_AS_STRING(o); + #endif + result = PyRun_String(code, Py_file_input, globals, locals); } - - #if PY_MAJOR_VERSION >= 3 - code = PyBytes_AS_STRING(o); - #else - code = PyString_AS_STRING(o); - #endif - result = PyRun_String(code, Py_file_input, globals, locals); Py_XDECREF(s); return result; -- 2.26.2