summaryrefslogtreecommitdiffstats
path: root/Python/bltinmodule.c
diff options
context:
space:
mode:
authorGeorg Brandl <georg@python.org>2006-09-06 06:51:57 (GMT)
committerGeorg Brandl <georg@python.org>2006-09-06 06:51:57 (GMT)
commit7cae87ca7b0a3a7ce497cbd335c8ec82fe680476 (patch)
tree612cc46e728bef49b19f3d4bc26fa4951b2c1c83 /Python/bltinmodule.c
parent4e472e05bdddde72d91d6f25d6e048371cf3c9be (diff)
downloadcpython-7cae87ca7b0a3a7ce497cbd335c8ec82fe680476.zip
cpython-7cae87ca7b0a3a7ce497cbd335c8ec82fe680476.tar.gz
cpython-7cae87ca7b0a3a7ce497cbd335c8ec82fe680476.tar.bz2
Patch #1550800: make exec a function.
Diffstat (limited to 'Python/bltinmodule.c')
-rw-r--r--Python/bltinmodule.c111
1 files changed, 110 insertions, 1 deletions
diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c
index 200ec26..94d4bc3 100644
--- a/Python/bltinmodule.c
+++ b/Python/bltinmodule.c
@@ -403,7 +403,7 @@ PyDoc_STRVAR(compile_doc,
"compile(source, filename, mode[, flags[, dont_inherit]]) -> code object\n\
\n\
Compile the source string (a Python module, statement or expression)\n\
-into a code object that can be executed by the exec statement or eval().\n\
+into a code object that can be executed by exec() or eval().\n\
The filename will be used for run-time error messages.\n\
The mode must be 'exec' to compile a module, 'single' to compile a\n\
single (interactive) statement, or 'eval' to compile an expression.\n\
@@ -543,6 +543,114 @@ The globals must be a dictionary and locals can be any mappping,\n\
defaulting to the current globals and locals.\n\
If only globals is given, locals defaults to it.\n");
+static PyObject *
+builtin_exec(PyObject *self, PyObject *args)
+{
+ PyObject *v;
+ PyObject *prog, *globals = Py_None, *locals = Py_None;
+ int plain = 0;
+
+ if (!PyArg_ParseTuple(args, "O|OO:exec", &prog, &globals, &locals))
+ return NULL;
+
+ if (globals == Py_None) {
+ globals = PyEval_GetGlobals();
+ if (locals == Py_None) {
+ locals = PyEval_GetLocals();
+ plain = 1;
+ }
+ if (!globals || !locals) {
+ PyErr_SetString(PyExc_SystemError,
+ "globals and locals cannot be NULL");
+ return NULL;
+ }
+ }
+ else if (locals == Py_None)
+ locals = globals;
+ if (!PyString_Check(prog) &&
+ !PyUnicode_Check(prog) &&
+ !PyCode_Check(prog) &&
+ !PyFile_Check(prog)) {
+ PyErr_Format(PyExc_TypeError,
+ "exec() arg 1 must be a string, file, or code "
+ "object, not %.100s", prog->ob_type->tp_name);
+ return NULL;
+ }
+ if (!PyDict_Check(globals)) {
+ PyErr_Format(PyExc_TypeError, "exec() arg 2 must be a dict, not %.100s",
+ globals->ob_type->tp_name);
+ return NULL;
+ }
+ if (!PyMapping_Check(locals)) {
+ PyErr_Format(PyExc_TypeError,
+ "arg 3 must be a mapping or None, not %.100s",
+ locals->ob_type->tp_name);
+ return NULL;
+ }
+ if (PyDict_GetItemString(globals, "__builtins__") == NULL) {
+ if (PyDict_SetItemString(globals, "__builtins__",
+ PyEval_GetBuiltins()) != 0)
+ return NULL;
+ }
+
+ if (PyCode_Check(prog)) {
+ if (PyCode_GetNumFree((PyCodeObject *)prog) > 0) {
+ PyErr_SetString(PyExc_TypeError,
+ "code object passed to exec() may not "
+ "contain free variables");
+ return NULL;
+ }
+ v = PyEval_EvalCode((PyCodeObject *) prog, globals, locals);
+ }
+ else if (PyFile_Check(prog)) {
+ FILE *fp = PyFile_AsFile(prog);
+ char *name = PyString_AsString(PyFile_Name(prog));
+ PyCompilerFlags cf;
+ cf.cf_flags = 0;
+ if (PyEval_MergeCompilerFlags(&cf))
+ v = PyRun_FileFlags(fp, name, Py_file_input, globals,
+ locals, &cf);
+ else
+ v = PyRun_File(fp, name, Py_file_input, globals,
+ locals);
+ }
+ else {
+ PyObject *tmp = NULL;
+ char *str;
+ PyCompilerFlags cf;
+ cf.cf_flags = 0;
+#ifdef Py_USING_UNICODE
+ if (PyUnicode_Check(prog)) {
+ tmp = PyUnicode_AsUTF8String(prog);
+ if (tmp == NULL)
+ return NULL;
+ prog = tmp;
+ cf.cf_flags |= PyCF_SOURCE_IS_UTF8;
+ }
+#endif
+ if (PyString_AsStringAndSize(prog, &str, NULL))
+ return NULL;
+ if (PyEval_MergeCompilerFlags(&cf))
+ v = PyRun_StringFlags(str, Py_file_input, globals,
+ locals, &cf);
+ else
+ v = PyRun_String(str, Py_file_input, globals, locals);
+ Py_XDECREF(tmp);
+ }
+ if (v == NULL)
+ return NULL;
+ Py_DECREF(v);
+ Py_RETURN_NONE;
+}
+
+PyDoc_STRVAR(exec_doc,
+"exec(object[, globals[, locals]])\n\
+\n\
+Read and execute code from a object, which can be a string, a code\n\
+object or a file object.\n\
+The globals and locals are dictionaries, defaulting to the current\n\
+globals and locals. If only globals is given, locals defaults to it.");
+
static PyObject *
builtin_execfile(PyObject *self, PyObject *args)
@@ -1884,6 +1992,7 @@ static PyMethodDef builtin_methods[] = {
{"dir", builtin_dir, METH_VARARGS, dir_doc},
{"divmod", builtin_divmod, METH_VARARGS, divmod_doc},
{"eval", builtin_eval, METH_VARARGS, eval_doc},
+ {"exec", builtin_exec, METH_VARARGS, exec_doc},
{"execfile", builtin_execfile, METH_VARARGS, execfile_doc},
{"filter", builtin_filter, METH_VARARGS, filter_doc},
{"getattr", builtin_getattr, METH_VARARGS, getattr_doc},