an object is listed in an 'except' clause.
# 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)
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.
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);
}
}
+/*
+ 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)
{
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);