Properly check for consistency with the third argument of

compile() when compiling an AST node.
This commit is contained in:
Georg Brandl 2008-03-29 13:24:23 +00:00
parent ea13dc629c
commit f2bfd54d6f
5 changed files with 54 additions and 26 deletions

View file

@ -5944,13 +5944,20 @@ PyObject* PyAST_mod2obj(mod_ty t)
return ast2obj_mod(t);
}
mod_ty PyAST_obj2mod(PyObject* ast, PyArena* arena)
/* mode is 0 for "exec", 1 for "eval" and 2 for "single" input */
mod_ty PyAST_obj2mod(PyObject* ast, PyArena* arena, int mode)
{
mod_ty res;
PyObject *req_type[] = {(PyObject*)Module_type, (PyObject*)Expression_type,
(PyObject*)Interactive_type};
char *req_name[] = {"Module", "Expression", "Interactive"};
assert(0 <= mode && mode <= 2);
init_types();
if (!PyObject_IsInstance(ast, (PyObject*)mod_type)) {
PyErr_SetString(PyExc_TypeError, "expected either Module, Interactive "
"or Expression node");
if (!PyObject_IsInstance(ast, req_type[mode])) {
PyErr_Format(PyExc_TypeError, "expected %s node, got %.400s",
req_name[mode], Py_TYPE(ast)->tp_name);
return NULL;
}
if (obj2ast_mod(ast, &res, arena) != 0)

View file

@ -466,7 +466,7 @@ builtin_compile(PyObject *self, PyObject *args, PyObject *kwds)
char *str;
char *filename;
char *startstr;
int start;
int mode = -1;
int dont_inherit = 0;
int supplied_flags = 0;
PyCompilerFlags cf;
@ -474,6 +474,7 @@ builtin_compile(PyObject *self, PyObject *args, PyObject *kwds)
Py_ssize_t length;
static char *kwlist[] = {"source", "filename", "mode", "flags",
"dont_inherit", NULL};
int start[] = {Py_file_input, Py_eval_input, Py_single_input};
if (!PyArg_ParseTupleAndKeywords(args, kwds, "Oss|ii:compile",
kwlist, &cmd, &filename, &startstr,
@ -495,6 +496,18 @@ builtin_compile(PyObject *self, PyObject *args, PyObject *kwds)
PyEval_MergeCompilerFlags(&cf);
}
if (strcmp(startstr, "exec") == 0)
mode = 0;
else if (strcmp(startstr, "eval") == 0)
mode = 1;
else if (strcmp(startstr, "single") == 0)
mode = 2;
else {
PyErr_SetString(PyExc_ValueError,
"compile() arg 3 must be 'exec', 'eval' or 'single'");
return NULL;
}
if (PyAST_Check(cmd)) {
if (supplied_flags & PyCF_ONLY_AST) {
Py_INCREF(cmd);
@ -505,7 +518,7 @@ builtin_compile(PyObject *self, PyObject *args, PyObject *kwds)
mod_ty mod;
arena = PyArena_New();
mod = PyAST_obj2mod(cmd, arena);
mod = PyAST_obj2mod(cmd, arena, mode);
if (mod == NULL) {
PyArena_Free(arena);
return NULL;
@ -526,19 +539,6 @@ builtin_compile(PyObject *self, PyObject *args, PyObject *kwds)
cf.cf_flags |= PyCF_SOURCE_IS_UTF8;
}
#endif
/* XXX: is it possible to pass start to the PyAST_ branch? */
if (strcmp(startstr, "exec") == 0)
start = Py_file_input;
else if (strcmp(startstr, "eval") == 0)
start = Py_eval_input;
else if (strcmp(startstr, "single") == 0)
start = Py_single_input;
else {
PyErr_SetString(PyExc_ValueError,
"compile() arg 3 must be 'exec'"
"or 'eval' or 'single'");
goto cleanup;
}
if (PyObject_AsReadBuffer(cmd, (const void **)&str, &length))
goto cleanup;
@ -547,7 +547,7 @@ builtin_compile(PyObject *self, PyObject *args, PyObject *kwds)
"compile() expected string without null bytes");
goto cleanup;
}
result = Py_CompileStringFlags(str, filename, start, &cf);
result = Py_CompileStringFlags(str, filename, start[mode], &cf);
cleanup:
Py_XDECREF(tmp);
return result;