Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions Lib/test/test_raise.py
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,20 @@ def test_class_cause(self):
else:
self.fail("No exception raised")

def test_class_cause_nonexception_result(self):
class ConstructsNone(BaseException):
@classmethod
def __new__(*args, **kwargs):
return None
try:
raise IndexError from ConstructsNone
except TypeError as e:
self.assertIn("should have returned an instance of BaseException", str(e))
except IndexError:
self.fail("Wrong kind of exception raised")
else:
self.fail("No exception raised")

def test_instance_cause(self):
cause = KeyError()
try:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Add check for the type of ``__cause__`` returned from calling the type ``T`` in ``raise from T``.
7 changes: 7 additions & 0 deletions Python/ceval.c
Original file line number Diff line number Diff line change
Expand Up @@ -1920,6 +1920,13 @@ do_raise(PyThreadState *tstate, PyObject *exc, PyObject *cause)
fixed_cause = _PyObject_CallNoArgs(cause);
if (fixed_cause == NULL)
goto raise_error;
if (!PyExceptionInstance_Check(fixed_cause)) {
_PyErr_Format(tstate, PyExc_TypeError,
"calling %R should have returned an instance of "
"BaseException, not %R",
cause, Py_TYPE(fixed_cause));
goto raise_error;
}
Py_DECREF(cause);
}
else if (PyExceptionInstance_Check(cause)) {
Expand Down