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

Skip to content

Commit e68140d

Browse files
author
Paul Prescod
committed
Better error message with UnboundLocalError
1 parent 408e9ae commit e68140d

1 file changed

Lines changed: 39 additions & 11 deletions

File tree

Python/ceval.c

Lines changed: 39 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,12 @@ static int exec_statement(PyFrameObject *,
7373
PyObject *, PyObject *, PyObject *);
7474
static void set_exc_info(PyThreadState *, PyObject *, PyObject *, PyObject *);
7575
static void reset_exc_info(PyThreadState *);
76+
static void format_exc_check_arg(PyObject *, char *, PyObject *);
7677

78+
#define NAME_ERROR_MSG \
79+
"There is no variable named '%s'"
80+
#define UNBOUNDLOCAL_ERROR_MSG \
81+
"Local variable '%.200s' referenced before assignment"
7782

7883
/* Dynamic execution profile */
7984
#ifdef DYNAMIC_EXECUTION_PROFILE
@@ -1396,7 +1401,8 @@ eval_code2(PyCodeObject *co, PyObject *globals, PyObject *locals,
13961401
break;
13971402
}
13981403
if ((err = PyDict_DelItem(x, w)) != 0)
1399-
PyErr_SetObject(PyExc_NameError, w);
1404+
format_exc_check_arg(PyExc_NameError,
1405+
NAME_ERROR_MSG ,w);
14001406
break;
14011407

14021408
case UNPACK_SEQUENCE:
@@ -1471,7 +1477,8 @@ eval_code2(PyCodeObject *co, PyObject *globals, PyObject *locals,
14711477
case DELETE_GLOBAL:
14721478
w = GETNAMEV(oparg);
14731479
if ((err = PyDict_DelItem(f->f_globals, w)) != 0)
1474-
PyErr_SetObject(PyExc_NameError, w);
1480+
format_exc_check_arg(
1481+
PyExc_NameError, NAME_ERROR_MSG ,w);
14751482
break;
14761483

14771484
case LOAD_CONST:
@@ -1493,8 +1500,9 @@ eval_code2(PyCodeObject *co, PyObject *globals, PyObject *locals,
14931500
if (x == NULL) {
14941501
x = PyDict_GetItem(f->f_builtins, w);
14951502
if (x == NULL) {
1496-
PyErr_SetObject(
1497-
PyExc_NameError, w);
1503+
format_exc_check_arg(
1504+
PyExc_NameError,
1505+
NAME_ERROR_MSG ,w);
14981506
break;
14991507
}
15001508
}
@@ -1509,7 +1517,9 @@ eval_code2(PyCodeObject *co, PyObject *globals, PyObject *locals,
15091517
if (x == NULL) {
15101518
x = PyDict_GetItem(f->f_builtins, w);
15111519
if (x == NULL) {
1512-
PyErr_SetObject(PyExc_NameError, w);
1520+
format_exc_check_arg(
1521+
PyExc_NameError,
1522+
NAME_ERROR_MSG ,w);
15131523
break;
15141524
}
15151525
}
@@ -1520,9 +1530,11 @@ eval_code2(PyCodeObject *co, PyObject *globals, PyObject *locals,
15201530
case LOAD_FAST:
15211531
x = GETLOCAL(oparg);
15221532
if (x == NULL) {
1523-
PyErr_SetObject(PyExc_UnboundLocalError,
1524-
PyTuple_GetItem(co->co_varnames,
1525-
oparg));
1533+
format_exc_check_arg(
1534+
PyExc_UnboundLocalError,
1535+
UNBOUNDLOCAL_ERROR_MSG,
1536+
PyTuple_GetItem(co->co_varnames, oparg)
1537+
);
15261538
break;
15271539
}
15281540
Py_INCREF(x);
@@ -1538,9 +1550,11 @@ eval_code2(PyCodeObject *co, PyObject *globals, PyObject *locals,
15381550
case DELETE_FAST:
15391551
x = GETLOCAL(oparg);
15401552
if (x == NULL) {
1541-
PyErr_SetObject(PyExc_UnboundLocalError,
1542-
PyTuple_GetItem(co->co_varnames,
1543-
oparg));
1553+
format_exc_check_arg(
1554+
PyExc_UnboundLocalError,
1555+
UNBOUNDLOCAL_ERROR_MSG,
1556+
PyTuple_GetItem(co->co_varnames, oparg)
1557+
);
15441558
break;
15451559
}
15461560
SETLOCAL(oparg, NULL);
@@ -3063,6 +3077,20 @@ exec_statement(PyFrameObject *f, PyObject *prog, PyObject *globals,
30633077
return 0;
30643078
}
30653079

3080+
static void
3081+
format_exc_check_arg(PyObject *exc, char *format_str, PyObject *obj)
3082+
{
3083+
char *obj_str;
3084+
3085+
if (!obj)
3086+
return;
3087+
3088+
obj_str = PyString_AsString(obj);
3089+
if (!obj_str)
3090+
return;
3091+
3092+
PyErr_Format(exc, format_str, obj_str);
3093+
}
30663094

30673095
#ifdef DYNAMIC_EXECUTION_PROFILE
30683096

0 commit comments

Comments
 (0)