Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit f74225d

Browse files
committed
You can no longer catch non-BaseException objects; TypeError is raised if such
an object is listed in an 'except' clause.
1 parent 6baa4c4 commit f74225d

3 files changed

Lines changed: 35 additions & 46 deletions

File tree

Lib/test/test_pep352.py

Lines changed: 10 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -158,34 +158,17 @@ def test_raise_string(self):
158158
# Raising a string raises TypeError.
159159
self.raise_fails("spam")
160160

161+
def test_catch_non_BaseException(self):
162+
# Tryinng to catch an object that does not inherit from BaseException
163+
# is not allowed.
164+
class NonBaseException(object):
165+
pass
166+
self.catch_fails(NonBaseException)
167+
self.catch_fails(NonBaseException())
168+
161169
def test_catch_string(self):
162-
# Catching a string should trigger a DeprecationWarning.
163-
with guard_warnings_filter():
164-
warnings.resetwarnings()
165-
warnings.filterwarnings("error")
166-
str_exc = "spam"
167-
try:
168-
try:
169-
raise StandardError
170-
except str_exc:
171-
pass
172-
except DeprecationWarning:
173-
pass
174-
except StandardError:
175-
self.fail("catching a string exception did not raise "
176-
"DeprecationWarning")
177-
# Make sure that even if the string exception is listed in a tuple
178-
# that a warning is raised.
179-
try:
180-
try:
181-
raise StandardError
182-
except (AssertionError, str_exc):
183-
pass
184-
except DeprecationWarning:
185-
pass
186-
except StandardError:
187-
self.fail("catching a string exception specified in a tuple did "
188-
"not raise DeprecationWarning")
170+
# Catching a string is bad.
171+
self.catch_fails("spam")
189172

190173
def test_main():
191174
run_unittest(ExceptionClassTests, UsageTests)

Misc/NEWS

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ TO DO
2828
Core and Builtins
2929
-----------------
3030

31+
- Objects listed in an 'except' clause must inherit from BaseException.
32+
3133
- PEP 3106: dict.iterkeys(), .iteritems(), .itervalues() are now gone;
3234
and .keys(), .items(), .values() return dict views.
3335

Python/ceval.c

Lines changed: 23 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1571,7 +1571,7 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
15711571
why == WHY_CONTINUE)
15721572
retval = POP();
15731573
}
1574-
else if (PyExceptionClass_Check(v) || PyString_Check(v)) {
1574+
else if (PyExceptionClass_Check(v)) {
15751575
w = POP();
15761576
u = POP();
15771577
PyErr_Restore(v, w, u);
@@ -3916,6 +3916,24 @@ assign_slice(PyObject *u, PyObject *v, PyObject *w, PyObject *x)
39163916
}
39173917
}
39183918

3919+
/*
3920+
Return a true value if the exception is allowed to be in an 'except' clause,
3921+
otherwise return a false value.
3922+
*/
3923+
static int
3924+
can_catch_exc(PyObject *exc)
3925+
{
3926+
if (!(PyExceptionClass_Check(exc) || PyExceptionInstance_Check(exc))) {
3927+
PyErr_SetString(PyExc_TypeError,
3928+
"catching an object must be a class or "
3929+
"instance of BaseException");
3930+
return 0;
3931+
}
3932+
else {
3933+
return 1;
3934+
}
3935+
}
3936+
39193937
static PyObject *
39203938
cmp_outcome(int op, register PyObject *v, register PyObject *w)
39213939
{
@@ -3944,28 +3962,14 @@ cmp_outcome(int op, register PyObject *v, register PyObject *w)
39443962
length = PyTuple_Size(w);
39453963
for (i = 0; i < length; i += 1) {
39463964
PyObject *exc = PyTuple_GET_ITEM(w, i);
3947-
if (PyString_Check(exc)) {
3948-
int ret_val;
3949-
ret_val = PyErr_WarnEx(
3950-
PyExc_DeprecationWarning,
3951-
"catching of string "
3952-
"exceptions is "
3953-
"deprecated", 1);
3954-
if (ret_val == -1)
3955-
return NULL;
3965+
if (!can_catch_exc(exc)) {
3966+
return NULL;
39563967
}
39573968
}
39583969
}
39593970
else {
3960-
if (PyString_Check(w)) {
3961-
int ret_val;
3962-
ret_val = PyErr_WarnEx(
3963-
PyExc_DeprecationWarning,
3964-
"catching of string "
3965-
"exceptions is deprecated",
3966-
1);
3967-
if (ret_val == -1)
3968-
return NULL;
3971+
if (!can_catch_exc(w)) {
3972+
return NULL;
39693973
}
39703974
}
39713975
res = PyErr_GivenExceptionMatches(v, w);

0 commit comments

Comments
 (0)