Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 5acc0c0

Browse files
committed
Fix symbol table pass to generation SyntaxError exceptions that
include the filename and line number.
1 parent dbfb662 commit 5acc0c0

2 files changed

Lines changed: 47 additions & 32 deletions

File tree

Include/symtable.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ extern "C" {
4343
struct symtable {
4444
int st_pass; /* pass == 1 or 2 */
4545
int st_keep; /* true if symtable will be returned */
46+
char *st_filename; /* name of file being compiled */
4647
PyObject *st_symbols; /* dictionary of symbol tables */
4748
PyObject *st_varnames; /* dictionary of parameter lists */
4849
PyObject *st_stack; /* stack of namespace info */

Python/compile.c

Lines changed: 46 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -371,40 +371,23 @@ int is_free(int v)
371371
/* Error message including line number */
372372

373373
static void
374-
com_error(struct compiling *c, PyObject *exc, char *msg)
374+
set_error_location(char *filename, int lineno)
375375
{
376-
PyObject *v, *tb, *tmp;
377-
if (c == NULL) {
378-
/* Error occurred via symtable call to
379-
is_constant_false */
380-
PyErr_SetString(exc, msg);
381-
return;
382-
}
383-
c->c_errors++;
384-
if (c->c_lineno <= 1) {
385-
/* Unknown line number or single interactive command */
386-
PyErr_SetString(exc, msg);
387-
return;
388-
}
389-
v = PyString_FromString(msg);
390-
if (v == NULL)
391-
return; /* MemoryError, too bad */
392-
PyErr_SetObject(exc, v);
393-
Py_DECREF(v);
376+
PyObject *exc, *v, *tb, *tmp;
394377

395378
/* add attributes for the line number and filename for the error */
396379
PyErr_Fetch(&exc, &v, &tb);
397380
PyErr_NormalizeException(&exc, &v, &tb);
398-
tmp = PyInt_FromLong(c->c_lineno);
381+
tmp = PyInt_FromLong(lineno);
399382
if (tmp == NULL)
400383
PyErr_Clear();
401384
else {
402385
if (PyObject_SetAttrString(v, "lineno", tmp))
403386
PyErr_Clear();
404387
Py_DECREF(tmp);
405388
}
406-
if (c->c_filename != NULL) {
407-
tmp = PyString_FromString(c->c_filename);
389+
if (filename != NULL) {
390+
tmp = PyString_FromString(filename);
408391
if (tmp == NULL)
409392
PyErr_Clear();
410393
else {
@@ -416,6 +399,31 @@ com_error(struct compiling *c, PyObject *exc, char *msg)
416399
PyErr_Restore(exc, v, tb);
417400
}
418401

402+
static void
403+
com_error(struct compiling *c, PyObject *exc, char *msg)
404+
{
405+
PyObject *v;
406+
if (c == NULL) {
407+
/* Error occurred via symtable call to
408+
is_constant_false */
409+
PyErr_SetString(exc, msg);
410+
return;
411+
}
412+
c->c_errors++;
413+
if (c->c_lineno <= 1) {
414+
/* Unknown line number or single interactive command */
415+
PyErr_SetString(exc, msg);
416+
return;
417+
}
418+
v = PyString_FromString(msg);
419+
if (v == NULL)
420+
return; /* MemoryError, too bad */
421+
PyErr_SetObject(exc, v);
422+
Py_DECREF(v);
423+
424+
set_error_location(c->c_filename, c->c_lineno);
425+
}
426+
419427

420428
/* Interface to the block stack */
421429

@@ -3804,6 +3812,7 @@ PyNode_CompileSymtable(node *n, char *filename)
38043812
st = symtable_init(1);
38053813
if (st == NULL)
38063814
return NULL;
3815+
assert(st->st_symbols != NULL);
38073816
symtable_enter_scope(st, TOP, TYPE(n), n->n_lineno);
38083817
if (st->st_errors > 0) {
38093818
PySymtable_Free(st);
@@ -3952,6 +3961,7 @@ symtable_build(struct compiling *c, node *n)
39523961
{
39533962
if ((c->c_symtable = symtable_init(0)) == NULL)
39543963
return -1;
3964+
c->c_symtable->st_filename = c->c_filename;
39553965
symtable_enter_scope(c->c_symtable, TOP, TYPE(n), n->n_lineno);
39563966
if (c->c_symtable->st_errors > 0)
39573967
return -1;
@@ -4057,11 +4067,11 @@ symtable_load_symbols(struct compiling *c)
40574067
else if (info & DEF_GLOBAL) {
40584068
if ((info & DEF_PARAM)
40594069
&& (PyString_AS_STRING(name)[0] != '.')){
4060-
char buf[500];
4061-
sprintf(buf,
4062-
"name '%.400s' is local and global",
4063-
PyString_AS_STRING(name));
4064-
com_error(c, PyExc_SyntaxError, buf);
4070+
PyErr_Format(PyExc_SyntaxError,
4071+
"name '%.400s' is local and global",
4072+
PyString_AS_STRING(name));
4073+
set_error_location(st->st_filename,
4074+
st->st_cur_lineno);
40654075
goto fail;
40664076
}
40674077
if (PyDict_SetItem(c->c_globals, name, Py_None) < 0)
@@ -4119,13 +4129,12 @@ symtable_load_symbols(struct compiling *c)
41194129
if (PyDict_GetItemString(st->st_cur, NOOPT) == NULL)
41204130
c->c_flags |= CO_OPTIMIZED;
41214131
else if (ncells || nfrees) {
4122-
char buf[256];
4123-
/* XXX need better error message */
4124-
sprintf(buf,
4132+
PyErr_Format(PyExc_SyntaxError,
41254133
"function %.100s: may not use lexical scoping"
41264134
" and 'import *' or exec in same function",
41274135
PyString_AS_STRING(st->st_cur_name));
4128-
com_error(c, PyExc_SyntaxError, buf);
4136+
set_error_location(st->st_filename,
4137+
st->st_cur_lineno);
41294138
return -1;
41304139
}
41314140
}
@@ -4148,6 +4157,7 @@ symtable_init(int keep)
41484157
return NULL;
41494158
st->st_pass = 1;
41504159
st->st_keep = keep;
4160+
st->st_filename = NULL;
41514161
if ((st->st_stack = PyList_New(0)) == NULL)
41524162
goto fail;
41534163
if ((st->st_symbols = PyDict_New()) == NULL)
@@ -4160,14 +4170,14 @@ symtable_init(int keep)
41604170
goto fail;
41614171
if (PyDict_SetItemString(st->st_symbols, TOP, d) < 0)
41624172
goto fail;
4173+
st->st_global = d;
41634174
Py_DECREF(d);
41644175
if (keep) {
41654176
if ((d = PyDict_New()) == NULL)
41664177
goto fail;
41674178
st->st_scopes = d;
41684179
} else
41694180
st->st_scopes = NULL;
4170-
st->st_global = d; /* use ref borrowed from st->st_symbols */
41714181
st->st_cur = NULL;
41724182
st->st_cur_id = NULL;
41734183
st->st_cur_name = NULL;
@@ -4505,6 +4515,8 @@ symtable_add_def_o(struct symtable *st, PyObject *dict,
45054515
if ((flag & DEF_PARAM) && (val & DEF_PARAM)) {
45064516
PyErr_Format(PyExc_SyntaxError, DUPLICATE_ARGUMENT,
45074517
PyString_AsString(name));
4518+
set_error_location(st->st_filename,
4519+
st->st_cur_lineno);
45084520
return -1;
45094521
}
45104522
val |= flag;
@@ -4844,6 +4856,8 @@ symtable_import(struct symtable *st, node *n)
48444856
if (st->st_cur_type != TYPE_MODULE) {
48454857
PyErr_SetString(PyExc_SyntaxError,
48464858
ILLEGAL_IMPORT_STAR);
4859+
set_error_location(st->st_filename,
4860+
n->n_lineno);
48474861
st->st_errors++;
48484862
return;
48494863
}

0 commit comments

Comments
 (0)