[Python-3000-checkins] r53960 - in python/branches/p3yk: Lib/test/test_pep352.py Misc/NEWS Python/ceval.c

brett.cannon python-3000-checkins at python.org
Mon Feb 26 22:10:21 CET 2007


Author: brett.cannon
Date: Mon Feb 26 22:10:16 2007
New Revision: 53960

Modified:
   python/branches/p3yk/Lib/test/test_pep352.py
   python/branches/p3yk/Misc/NEWS
   python/branches/p3yk/Python/ceval.c
Log:
You can no longer catch non-BaseException objects; TypeError is raised if such
an object is listed in an 'except' clause.


Modified: python/branches/p3yk/Lib/test/test_pep352.py
==============================================================================
--- python/branches/p3yk/Lib/test/test_pep352.py	(original)
+++ python/branches/p3yk/Lib/test/test_pep352.py	Mon Feb 26 22:10:16 2007
@@ -158,34 +158,17 @@
         # 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)

Modified: python/branches/p3yk/Misc/NEWS
==============================================================================
--- python/branches/p3yk/Misc/NEWS	(original)
+++ python/branches/p3yk/Misc/NEWS	Mon Feb 26 22:10:16 2007
@@ -28,6 +28,8 @@
 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.
 

Modified: python/branches/p3yk/Python/ceval.c
==============================================================================
--- python/branches/p3yk/Python/ceval.c	(original)
+++ python/branches/p3yk/Python/ceval.c	Mon Feb 26 22:10:16 2007
@@ -1571,7 +1571,7 @@
 				    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 @@
 	}
 }
 
+/*
+   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 @@
 			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);


More information about the Python-3000-checkins mailing list