code object support in exec statement
authorAndrey Plotnikov <plotnikoff@gmail.com>
Wed, 19 Aug 2009 06:48:24 +0000 (14:48 +0800)
committerAndrey Plotnikov <plotnikoff@gmail.com>
Wed, 19 Aug 2009 06:48:24 +0000 (14:48 +0800)
Cython/Compiler/Builtin.py

index 57028e671311d926d1db643ed131bb6ffaa24a3d..5f85810a43e4f29b57ff8f05111671c63580ab22 100644 (file)
@@ -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;