Fix symbol table pass to generation SyntaxError exceptions that
include the filename and line number.
This commit is contained in:
parent
dbfb66296c
commit
5acc0c0cfc
|
@ -43,6 +43,7 @@ extern "C" {
|
||||||
struct symtable {
|
struct symtable {
|
||||||
int st_pass; /* pass == 1 or 2 */
|
int st_pass; /* pass == 1 or 2 */
|
||||||
int st_keep; /* true if symtable will be returned */
|
int st_keep; /* true if symtable will be returned */
|
||||||
|
char *st_filename; /* name of file being compiled */
|
||||||
PyObject *st_symbols; /* dictionary of symbol tables */
|
PyObject *st_symbols; /* dictionary of symbol tables */
|
||||||
PyObject *st_varnames; /* dictionary of parameter lists */
|
PyObject *st_varnames; /* dictionary of parameter lists */
|
||||||
PyObject *st_stack; /* stack of namespace info */
|
PyObject *st_stack; /* stack of namespace info */
|
||||||
|
|
|
@ -370,10 +370,39 @@ int is_free(int v)
|
||||||
|
|
||||||
/* Error message including line number */
|
/* Error message including line number */
|
||||||
|
|
||||||
|
static void
|
||||||
|
set_error_location(char *filename, int lineno)
|
||||||
|
{
|
||||||
|
PyObject *exc, *v, *tb, *tmp;
|
||||||
|
|
||||||
|
/* add attributes for the line number and filename for the error */
|
||||||
|
PyErr_Fetch(&exc, &v, &tb);
|
||||||
|
PyErr_NormalizeException(&exc, &v, &tb);
|
||||||
|
tmp = PyInt_FromLong(lineno);
|
||||||
|
if (tmp == NULL)
|
||||||
|
PyErr_Clear();
|
||||||
|
else {
|
||||||
|
if (PyObject_SetAttrString(v, "lineno", tmp))
|
||||||
|
PyErr_Clear();
|
||||||
|
Py_DECREF(tmp);
|
||||||
|
}
|
||||||
|
if (filename != NULL) {
|
||||||
|
tmp = PyString_FromString(filename);
|
||||||
|
if (tmp == NULL)
|
||||||
|
PyErr_Clear();
|
||||||
|
else {
|
||||||
|
if (PyObject_SetAttrString(v, "filename", tmp))
|
||||||
|
PyErr_Clear();
|
||||||
|
Py_DECREF(tmp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
PyErr_Restore(exc, v, tb);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
com_error(struct compiling *c, PyObject *exc, char *msg)
|
com_error(struct compiling *c, PyObject *exc, char *msg)
|
||||||
{
|
{
|
||||||
PyObject *v, *tb, *tmp;
|
PyObject *v;
|
||||||
if (c == NULL) {
|
if (c == NULL) {
|
||||||
/* Error occurred via symtable call to
|
/* Error occurred via symtable call to
|
||||||
is_constant_false */
|
is_constant_false */
|
||||||
|
@ -392,28 +421,7 @@ com_error(struct compiling *c, PyObject *exc, char *msg)
|
||||||
PyErr_SetObject(exc, v);
|
PyErr_SetObject(exc, v);
|
||||||
Py_DECREF(v);
|
Py_DECREF(v);
|
||||||
|
|
||||||
/* add attributes for the line number and filename for the error */
|
set_error_location(c->c_filename, c->c_lineno);
|
||||||
PyErr_Fetch(&exc, &v, &tb);
|
|
||||||
PyErr_NormalizeException(&exc, &v, &tb);
|
|
||||||
tmp = PyInt_FromLong(c->c_lineno);
|
|
||||||
if (tmp == NULL)
|
|
||||||
PyErr_Clear();
|
|
||||||
else {
|
|
||||||
if (PyObject_SetAttrString(v, "lineno", tmp))
|
|
||||||
PyErr_Clear();
|
|
||||||
Py_DECREF(tmp);
|
|
||||||
}
|
|
||||||
if (c->c_filename != NULL) {
|
|
||||||
tmp = PyString_FromString(c->c_filename);
|
|
||||||
if (tmp == NULL)
|
|
||||||
PyErr_Clear();
|
|
||||||
else {
|
|
||||||
if (PyObject_SetAttrString(v, "filename", tmp))
|
|
||||||
PyErr_Clear();
|
|
||||||
Py_DECREF(tmp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
PyErr_Restore(exc, v, tb);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -3804,6 +3812,7 @@ PyNode_CompileSymtable(node *n, char *filename)
|
||||||
st = symtable_init(1);
|
st = symtable_init(1);
|
||||||
if (st == NULL)
|
if (st == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
assert(st->st_symbols != NULL);
|
||||||
symtable_enter_scope(st, TOP, TYPE(n), n->n_lineno);
|
symtable_enter_scope(st, TOP, TYPE(n), n->n_lineno);
|
||||||
if (st->st_errors > 0) {
|
if (st->st_errors > 0) {
|
||||||
PySymtable_Free(st);
|
PySymtable_Free(st);
|
||||||
|
@ -3952,6 +3961,7 @@ symtable_build(struct compiling *c, node *n)
|
||||||
{
|
{
|
||||||
if ((c->c_symtable = symtable_init(0)) == NULL)
|
if ((c->c_symtable = symtable_init(0)) == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
|
c->c_symtable->st_filename = c->c_filename;
|
||||||
symtable_enter_scope(c->c_symtable, TOP, TYPE(n), n->n_lineno);
|
symtable_enter_scope(c->c_symtable, TOP, TYPE(n), n->n_lineno);
|
||||||
if (c->c_symtable->st_errors > 0)
|
if (c->c_symtable->st_errors > 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -4057,11 +4067,11 @@ symtable_load_symbols(struct compiling *c)
|
||||||
else if (info & DEF_GLOBAL) {
|
else if (info & DEF_GLOBAL) {
|
||||||
if ((info & DEF_PARAM)
|
if ((info & DEF_PARAM)
|
||||||
&& (PyString_AS_STRING(name)[0] != '.')){
|
&& (PyString_AS_STRING(name)[0] != '.')){
|
||||||
char buf[500];
|
PyErr_Format(PyExc_SyntaxError,
|
||||||
sprintf(buf,
|
"name '%.400s' is local and global",
|
||||||
"name '%.400s' is local and global",
|
PyString_AS_STRING(name));
|
||||||
PyString_AS_STRING(name));
|
set_error_location(st->st_filename,
|
||||||
com_error(c, PyExc_SyntaxError, buf);
|
st->st_cur_lineno);
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
if (PyDict_SetItem(c->c_globals, name, Py_None) < 0)
|
if (PyDict_SetItem(c->c_globals, name, Py_None) < 0)
|
||||||
|
@ -4119,13 +4129,12 @@ symtable_load_symbols(struct compiling *c)
|
||||||
if (PyDict_GetItemString(st->st_cur, NOOPT) == NULL)
|
if (PyDict_GetItemString(st->st_cur, NOOPT) == NULL)
|
||||||
c->c_flags |= CO_OPTIMIZED;
|
c->c_flags |= CO_OPTIMIZED;
|
||||||
else if (ncells || nfrees) {
|
else if (ncells || nfrees) {
|
||||||
char buf[256];
|
PyErr_Format(PyExc_SyntaxError,
|
||||||
/* XXX need better error message */
|
|
||||||
sprintf(buf,
|
|
||||||
"function %.100s: may not use lexical scoping"
|
"function %.100s: may not use lexical scoping"
|
||||||
" and 'import *' or exec in same function",
|
" and 'import *' or exec in same function",
|
||||||
PyString_AS_STRING(st->st_cur_name));
|
PyString_AS_STRING(st->st_cur_name));
|
||||||
com_error(c, PyExc_SyntaxError, buf);
|
set_error_location(st->st_filename,
|
||||||
|
st->st_cur_lineno);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4148,6 +4157,7 @@ symtable_init(int keep)
|
||||||
return NULL;
|
return NULL;
|
||||||
st->st_pass = 1;
|
st->st_pass = 1;
|
||||||
st->st_keep = keep;
|
st->st_keep = keep;
|
||||||
|
st->st_filename = NULL;
|
||||||
if ((st->st_stack = PyList_New(0)) == NULL)
|
if ((st->st_stack = PyList_New(0)) == NULL)
|
||||||
goto fail;
|
goto fail;
|
||||||
if ((st->st_symbols = PyDict_New()) == NULL)
|
if ((st->st_symbols = PyDict_New()) == NULL)
|
||||||
|
@ -4160,6 +4170,7 @@ symtable_init(int keep)
|
||||||
goto fail;
|
goto fail;
|
||||||
if (PyDict_SetItemString(st->st_symbols, TOP, d) < 0)
|
if (PyDict_SetItemString(st->st_symbols, TOP, d) < 0)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
st->st_global = d;
|
||||||
Py_DECREF(d);
|
Py_DECREF(d);
|
||||||
if (keep) {
|
if (keep) {
|
||||||
if ((d = PyDict_New()) == NULL)
|
if ((d = PyDict_New()) == NULL)
|
||||||
|
@ -4167,7 +4178,6 @@ symtable_init(int keep)
|
||||||
st->st_scopes = d;
|
st->st_scopes = d;
|
||||||
} else
|
} else
|
||||||
st->st_scopes = NULL;
|
st->st_scopes = NULL;
|
||||||
st->st_global = d; /* use ref borrowed from st->st_symbols */
|
|
||||||
st->st_cur = NULL;
|
st->st_cur = NULL;
|
||||||
st->st_cur_id = NULL;
|
st->st_cur_id = NULL;
|
||||||
st->st_cur_name = NULL;
|
st->st_cur_name = NULL;
|
||||||
|
@ -4505,6 +4515,8 @@ symtable_add_def_o(struct symtable *st, PyObject *dict,
|
||||||
if ((flag & DEF_PARAM) && (val & DEF_PARAM)) {
|
if ((flag & DEF_PARAM) && (val & DEF_PARAM)) {
|
||||||
PyErr_Format(PyExc_SyntaxError, DUPLICATE_ARGUMENT,
|
PyErr_Format(PyExc_SyntaxError, DUPLICATE_ARGUMENT,
|
||||||
PyString_AsString(name));
|
PyString_AsString(name));
|
||||||
|
set_error_location(st->st_filename,
|
||||||
|
st->st_cur_lineno);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
val |= flag;
|
val |= flag;
|
||||||
|
@ -4844,6 +4856,8 @@ symtable_import(struct symtable *st, node *n)
|
||||||
if (st->st_cur_type != TYPE_MODULE) {
|
if (st->st_cur_type != TYPE_MODULE) {
|
||||||
PyErr_SetString(PyExc_SyntaxError,
|
PyErr_SetString(PyExc_SyntaxError,
|
||||||
ILLEGAL_IMPORT_STAR);
|
ILLEGAL_IMPORT_STAR);
|
||||||
|
set_error_location(st->st_filename,
|
||||||
|
n->n_lineno);
|
||||||
st->st_errors++;
|
st->st_errors++;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue