#
from Symtab import BuiltinScope, StructOrUnionScope
-from Cython.Utils import UtilityCode
+from Code import UtilityCode
from TypeSlots import Signature
import PyrexTypes
import Naming
#('eval', "", "", ""),
#('execfile', "", "", ""),
#('filter', "", "", ""),
- ('getattr', "OO", "O", "PyObject_GetAttr"),
+ #('getattr', "OO", "O", "PyObject_GetAttr"), # optimised later on
('getattr3', "OOO", "O", "__Pyx_GetAttr3", "getattr"),
('hasattr', "OO", "b", "PyObject_HasAttr"),
('hash', "O", "l", "PyObject_Hash"),
#('round', "", "", ""),
('setattr', "OOO", "r", "PyObject_SetAttr"),
#('sum', "", "", ""),
+ ('type', "O", "O", "PyObject_Type"),
#('unichr', "", "", ""),
#('unicode', "", "", ""),
#('vars', "", "", ""),
("tuple", "PyTuple_Type", []),
- ("list", "PyList_Type", [("append", "OO", "i", "PyList_Append"),
- ("insert", "OZO", "i", "PyList_Insert"),
-# ("sort", "O", "i", "PyList_Sort"), # has optional arguments
- ("reverse","O", "i", "PyList_Reverse")]),
+ ("list", "PyList_Type", [("insert", "OZO", "i", "PyList_Insert")]),
("dict", "PyDict_Type", [("items", "O", "O", "PyDict_Items"),
("keys", "O", "O", "PyDict_Keys"),
pyexec_utility_code = UtilityCode(
proto = """
+#if PY_VERSION_HEX < 0x02040000
+#ifndef Py_EVAL_H
+#include "eval.h"
+#endif
+#endif
static PyObject* __Pyx_PyRun(PyObject*, PyObject*, PyObject*);
""",
impl = """
static PyObject* __Pyx_PyRun(PyObject* o, PyObject* globals, PyObject* locals) {
PyObject* result;
PyObject* s = 0;
+ char *code = 0;
- if (!locals && !globals) {
+ if (!globals || globals == Py_None) {
globals = PyModule_GetDict(%s);""" % Naming.module_cname + """
if (!globals)
goto bad;
+ } else if (!PyDict_Check(globals)) {
+ PyErr_Format(PyExc_TypeError, "exec() arg 2 must be a dict, not %.100s",
+ globals->ob_type->tp_name);
+ goto bad;
+ }
+ if (!locals || locals == Py_None) {
locals = globals;
- } else if (!locals) {
- locals = globals;
- } else if (!globals) {
- 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());
}
- result = PyRun_String(
- #if PY_MAJOR_VERSION >= 3
- PyBytes_AS_STRING(o),
- #else
- PyString_AS_STRING(o),
- #endif
- Py_file_input, globals, locals);
+ if (PyCode_Check(o)) {
+ if (PyCode_GetNumFree((PyCodeObject *)o) > 0) {
+ PyErr_SetString(PyExc_TypeError,
+ "code object passed to exec() may not contain free variables");
+ goto bad;
+ }
+ result = PyEval_EvalCode((PyCodeObject *)o, globals, locals);
+ } else {
+ PyCompilerFlags cf;
+ cf.cf_flags = 0;
+ if (PyUnicode_Check(o)) {
+ cf.cf_flags = PyCF_SOURCE_IS_UTF8;
+ 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
+ if (PyEval_MergeCompilerFlags(&cf)) {
+ result = PyRun_StringFlags(code, Py_file_input, globals, locals, &cf);
+ } else {
+ result = PyRun_String(code, Py_file_input, globals, locals);
+ }
+ Py_XDECREF(s);
+ }
- Py_XDECREF(s);
return result;
bad:
Py_XDECREF(s);
init_builtin_funcs()
init_builtin_types()
init_builtin_structs()
- global list_type, tuple_type, dict_type, set_type, unicode_type, type_type
+ global list_type, tuple_type, dict_type, set_type, type_type
+ global bytes_type, str_type, unicode_type
type_type = builtin_scope.lookup('type').type
list_type = builtin_scope.lookup('list').type
tuple_type = builtin_scope.lookup('tuple').type
dict_type = builtin_scope.lookup('dict').type
set_type = builtin_scope.lookup('set').type
+ bytes_type = builtin_scope.lookup('bytes').type
+ str_type = builtin_scope.lookup('str').type
unicode_type = builtin_scope.lookup('unicode').type
init_builtins()