]> granicus.if.org Git - python/commitdiff
You can no longer catch non-BaseException objects; TypeError is raised if such
authorBrett Cannon <bcannon@gmail.com>
Mon, 26 Feb 2007 21:10:16 +0000 (21:10 +0000)
committerBrett Cannon <bcannon@gmail.com>
Mon, 26 Feb 2007 21:10:16 +0000 (21:10 +0000)
an object is listed in an 'except' clause.

Lib/test/test_pep352.py
Misc/NEWS
Python/ceval.c

index 15f1101832af3b2cc42d28f1444cb6d0146fc713..2a6bac1218c75a16f424a219cbf260ef08347924 100644 (file)
@@ -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)
index c20793e2ba226fa61cace8a691ed318f5bb6ec50..91e1f0256bdcb21f2ca3d35ecf8a9aa96b4f02c0 100644 (file)
--- 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.
 
index 5f1b873e3db46e32747663836cf69f5065c1e72b..86dcea28c1d338d0c7df9206e7397dbcf5bc527a 100644 (file)
@@ -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);