Change error message raised when free variable is not yet bound. It
now raises NameError instead of UnboundLocalError, because the var in
question is definitely not local. (This affects test_scope.py)
Also update the recent fix by Ping using get_func_name(). Replace
tests of get_func_name() return value with call to get_func_desc() to
match all the other uses.
diff --git a/Lib/test/test_scope.py b/Lib/test/test_scope.py
index d6367b2..358c45a 100644
--- a/Lib/test/test_scope.py
+++ b/Lib/test/test_scope.py
@@ -291,7 +291,7 @@
try:
errorInInner()
-except UnboundLocalError:
+except NameError:
pass
else:
raise TestFailed
@@ -435,3 +435,4 @@
verify(d.has_key('h'))
del d['h']
verify(d == {'x': 2, 'y': 7, 'w': 6})
+
diff --git a/Python/ceval.c b/Python/ceval.c
index a1b3bc2..b6686b6 100644
--- a/Python/ceval.c
+++ b/Python/ceval.c
@@ -83,6 +83,9 @@
"global name '%.200s' is not defined"
#define UNBOUNDLOCAL_ERROR_MSG \
"local variable '%.200s' referenced before assignment"
+#define UNBOUNDFREE_ERROR_MSG \
+ "free variable '%.200s' referenced before assignment" \
+ " in enclosing scope"
/* Dynamic execution profile */
#ifdef DYNAMIC_EXECUTION_PROFILE
@@ -1693,18 +1696,22 @@
x = freevars[oparg];
w = PyCell_Get(x);
if (w == NULL) {
- if (oparg < f->f_ncells)
+ if (oparg < f->f_ncells) {
v = PyTuple_GetItem(co->co_cellvars,
oparg);
- else
+ format_exc_check_arg(
+ PyExc_UnboundLocalError,
+ UNBOUNDLOCAL_ERROR_MSG,
+ v);
+ } else {
v = PyTuple_GetItem(
co->co_freevars,
oparg - f->f_ncells);
-
- format_exc_check_arg(
- PyExc_UnboundLocalError,
- UNBOUNDLOCAL_ERROR_MSG,
- v);
+ format_exc_check_arg(
+ PyExc_NameError,
+ UNBOUNDFREE_ERROR_MSG,
+ v);
+ }
err = -1;
break;
}
@@ -2883,11 +2890,10 @@
return NULL;
}
if (!ok) {
- char* fn = get_func_name(func);
PyErr_Format(PyExc_TypeError,
- "unbound method %s%smust be "
+ "unbound method %s%s must be "
"called with instance as first argument",
- fn ? fn : "", fn ? "() " : "");
+ get_func_name(func), get_func_desc(func));
return NULL;
}
Py_INCREF(arg);