summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Include/pyerrors.h1
-rw-r--r--Lib/exceptions.py8
-rw-r--r--Python/bltinmodule.c15
-rw-r--r--Python/ceval.c4
4 files changed, 25 insertions, 3 deletions
diff --git a/Include/pyerrors.h b/Include/pyerrors.h
index 8a8111a..becaabd 100644
--- a/Include/pyerrors.h
+++ b/Include/pyerrors.h
@@ -78,6 +78,7 @@ extern DL_IMPORT(PyObject *) PyExc_SyntaxError;
extern DL_IMPORT(PyObject *) PyExc_SystemError;
extern DL_IMPORT(PyObject *) PyExc_SystemExit;
extern DL_IMPORT(PyObject *) PyExc_TypeError;
+extern DL_IMPORT(PyObject *) PyExc_UnboundLocalError;
extern DL_IMPORT(PyObject *) PyExc_ValueError;
extern DL_IMPORT(PyObject *) PyExc_ZeroDivisionError;
diff --git a/Lib/exceptions.py b/Lib/exceptions.py
index e943f7b..af752d9 100644
--- a/Lib/exceptions.py
+++ b/Lib/exceptions.py
@@ -40,6 +40,8 @@ Exception(*)
| +-- NotImplementedError(*)
|
+-- NameError
+ | |
+ | +-- UnboundLocalError(*)
+-- AttributeError
+-- SyntaxError
+-- TypeError
@@ -208,7 +210,11 @@ class AttributeError(StandardError):
pass
class NameError(StandardError):
- """Name not found locally or globally."""
+ """Name not found globally."""
+ pass
+
+class UnboundLocalError(NameError):
+ """Local name referenced but not bound to a value."""
pass
class MemoryError(StandardError):
diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c
index 3ddf885..4e20eda 100644
--- a/Python/bltinmodule.c
+++ b/Python/bltinmodule.c
@@ -2232,6 +2232,7 @@ PyObject *PyExc_NotImplementedError;
PyObject *PyExc_SyntaxError;
PyObject *PyExc_SystemError;
PyObject *PyExc_SystemExit;
+PyObject *PyExc_UnboundLocalError;
PyObject *PyExc_TypeError;
PyObject *PyExc_ValueError;
PyObject *PyExc_ZeroDivisionError;
@@ -2261,6 +2262,11 @@ bltin_exc[] = {
{"KeyError", &PyExc_KeyError, 1},
{"KeyboardInterrupt", &PyExc_KeyboardInterrupt, 1},
{"MemoryError", &PyExc_MemoryError, 1},
+ /* Note: NameError is not a leaf in exceptions.py, but unlike
+ the other non-leafs NameError is meant to be raised directly
+ at times -- the leaf_exc member really seems to mean something
+ like "this is an abstract base class" when false.
+ */
{"NameError", &PyExc_NameError, 1},
{"OverflowError", &PyExc_OverflowError, 1},
{"RuntimeError", &PyExc_RuntimeError, 1},
@@ -2268,6 +2274,7 @@ bltin_exc[] = {
{"SyntaxError", &PyExc_SyntaxError, 1},
{"SystemError", &PyExc_SystemError, 1},
{"SystemExit", &PyExc_SystemExit, 1},
+ {"UnboundLocalError", &PyExc_UnboundLocalError, 1},
{"TypeError", &PyExc_TypeError, 1},
{"ValueError", &PyExc_ValueError, 1},
{"ZeroDivisionError", &PyExc_ZeroDivisionError, 1},
@@ -2420,6 +2427,14 @@ initerrors(dict)
PyTuple_SET_ITEM(PyExc_EnvironmentError, 1, PyExc_OSError);
PyDict_SetItemString(dict, "EnvironmentError", PyExc_EnvironmentError);
+ /* Make UnboundLocalError an alias for NameError */
+ Py_INCREF(PyExc_NameError);
+ Py_DECREF(PyExc_UnboundLocalError);
+ PyExc_UnboundLocalError = PyExc_NameError;
+ if (PyDict_SetItemString(dict, "UnboundLocalError",
+ PyExc_NameError) != 0)
+ Py_FatalError("Cannot create string-based exceptions");
+
/* missing from the StandardError tuple: Exception, StandardError,
* and SystemExit
*/
diff --git a/Python/ceval.c b/Python/ceval.c
index 6218397..1c51ccf 100644
--- a/Python/ceval.c
+++ b/Python/ceval.c
@@ -1320,7 +1320,7 @@ eval_code2(co, globals, locals,
case LOAD_FAST:
x = GETLOCAL(oparg);
if (x == NULL) {
- PyErr_SetObject(PyExc_NameError,
+ PyErr_SetObject(PyExc_UnboundLocalError,
PyTuple_GetItem(co->co_varnames,
oparg));
break;
@@ -1338,7 +1338,7 @@ eval_code2(co, globals, locals,
case DELETE_FAST:
x = GETLOCAL(oparg);
if (x == NULL) {
- PyErr_SetObject(PyExc_NameError,
+ PyErr_SetObject(PyExc_UnboundLocalError,
PyTuple_GetItem(co->co_varnames,
oparg));
break;