summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Lib/test/test_pep352.py37
-rw-r--r--Misc/NEWS2
-rw-r--r--Python/ceval.c42
3 files changed, 35 insertions, 46 deletions
diff --git a/Lib/test/test_pep352.py b/Lib/test/test_pep352.py
index 15f1101..2a6bac1 100644
--- a/Lib/test/test_pep352.py
+++ b/Lib/test/test_pep352.py
@@ -158,34 +158,17 @@ class UsageTests(unittest.TestCase):
# Raising a string raises TypeError.
self.raise_fails("spam")
+ def test_catch_non_BaseException(self):
+ # Tryinng to catch an object that does not inherit from BaseException
+ # is not allowed.
+ class NonBaseException(object):
+ pass
+ self.catch_fails(NonBaseException)
+ self.catch_fails(NonBaseException())
+
def test_catch_string(self):
- # Catching a string should trigger a DeprecationWarning.
- with guard_warnings_filter():
- warnings.resetwarnings()
- warnings.filterwarnings("error")
- str_exc = "spam"
- try:
- try:
- raise StandardError
- except str_exc:
- pass
- except DeprecationWarning:
- pass
- except StandardError:
- self.fail("catching a string exception did not raise "
- "DeprecationWarning")
- # Make sure that even if the string exception is listed in a tuple
- # that a warning is raised.
- try:
- try:
- raise StandardError
- except (AssertionError, str_exc):
- pass
- except DeprecationWarning:
- pass
- except StandardError:
- self.fail("catching a string exception specified in a tuple did "
- "not raise DeprecationWarning")
+ # Catching a string is bad.
+ self.catch_fails("spam")
def test_main():
run_unittest(ExceptionClassTests, UsageTests)
diff --git a/Misc/NEWS b/Misc/NEWS
index c20793e..91e1f02 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -28,6 +28,8 @@ TO DO
Core and Builtins
-----------------
+- Objects listed in an 'except' clause must inherit from BaseException.
+
- PEP 3106: dict.iterkeys(), .iteritems(), .itervalues() are now gone;
and .keys(), .items(), .values() return dict views.
diff --git a/Python/ceval.c b/Python/ceval.c
index 5f1b873..86dcea2 100644
--- a/Python/ceval.c
+++ b/Python/ceval.c
@@ -1571,7 +1571,7 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
why == WHY_CONTINUE)
retval = POP();
}
- else if (PyExceptionClass_Check(v) || PyString_Check(v)) {
+ else if (PyExceptionClass_Check(v)) {
w = POP();
u = POP();
PyErr_Restore(v, w, u);
@@ -3916,6 +3916,24 @@ assign_slice(PyObject *u, PyObject *v, PyObject *w, PyObject *x)
}
}
+/*
+ Return a true value if the exception is allowed to be in an 'except' clause,
+ otherwise return a false value.
+*/
+static int
+can_catch_exc(PyObject *exc)
+{
+ if (!(PyExceptionClass_Check(exc) || PyExceptionInstance_Check(exc))) {
+ PyErr_SetString(PyExc_TypeError,
+ "catching an object must be a class or "
+ "instance of BaseException");
+ return 0;
+ }
+ else {
+ return 1;
+ }
+}
+
static PyObject *
cmp_outcome(int op, register PyObject *v, register PyObject *w)
{
@@ -3944,28 +3962,14 @@ cmp_outcome(int op, register PyObject *v, register PyObject *w)
length = PyTuple_Size(w);
for (i = 0; i < length; i += 1) {
PyObject *exc = PyTuple_GET_ITEM(w, i);
- if (PyString_Check(exc)) {
- int ret_val;
- ret_val = PyErr_WarnEx(
- PyExc_DeprecationWarning,
- "catching of string "
- "exceptions is "
- "deprecated", 1);
- if (ret_val == -1)
- return NULL;
+ if (!can_catch_exc(exc)) {
+ return NULL;
}
}
}
else {
- if (PyString_Check(w)) {
- int ret_val;
- ret_val = PyErr_WarnEx(
- PyExc_DeprecationWarning,
- "catching of string "
- "exceptions is deprecated",
- 1);
- if (ret_val == -1)
- return NULL;
+ if (!can_catch_exc(w)) {
+ return NULL;
}
}
res = PyErr_GivenExceptionMatches(v, w);