bpo-45871: Refactor except matcher validation into a separate function so that it can be reused. Add missing unit test. (GH-29711)

This commit is contained in:
Irit Katriel 2021-11-22 16:56:23 +00:00 committed by GitHub
parent 0e1c2f3ef8
commit 4d6c0c0cce
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 48 additions and 23 deletions

View File

@ -2401,6 +2401,21 @@ class SyntaxErrorTests(unittest.TestCase):
self.assertRaises(TypeError, SyntaxError, "bad bad", args)
class TestInvalidExceptionMatcher(unittest.TestCase):
def test_except_star_invalid_exception_type(self):
with self.assertRaises(TypeError):
try:
raise ValueError
except 42:
pass
with self.assertRaises(TypeError):
try:
raise ValueError
except (ValueError, 42):
pass
class PEP626Tests(unittest.TestCase):
def lineno_after_raise(self, f, *expected):

View File

@ -93,6 +93,7 @@ static int import_all_from(PyThreadState *, PyObject *, PyObject *);
static void format_exc_check_arg(PyThreadState *, PyObject *, const char *, PyObject *);
static void format_exc_unbound(PyThreadState *tstate, PyCodeObject *co, int oparg);
static int check_args_iterable(PyThreadState *, PyObject *func, PyObject *vararg);
static int check_except_type_valid(PyThreadState *tstate, PyObject* right);
static void format_kwargs_error(PyThreadState *, PyObject *func, PyObject *kwargs);
static void format_awaitable_error(PyThreadState *, PyTypeObject *, int, int);
static int get_exception_handler(PyCodeObject *, int, int*, int*, int*);
@ -3715,31 +3716,11 @@ check_eval_breaker:
}
TARGET(JUMP_IF_NOT_EXC_MATCH) {
const char *cannot_catch_msg = "catching classes that do not "
"inherit from BaseException is not "
"allowed";
PyObject *right = POP();
PyObject *left = TOP();
if (PyTuple_Check(right)) {
Py_ssize_t i, length;
length = PyTuple_GET_SIZE(right);
for (i = 0; i < length; i++) {
PyObject *exc = PyTuple_GET_ITEM(right, i);
if (!PyExceptionClass_Check(exc)) {
_PyErr_SetString(tstate, PyExc_TypeError,
cannot_catch_msg);
Py_DECREF(right);
goto error;
}
}
}
else {
if (!PyExceptionClass_Check(right)) {
_PyErr_SetString(tstate, PyExc_TypeError,
cannot_catch_msg);
Py_DECREF(right);
goto error;
}
if (check_except_type_valid(tstate, right) < 0) {
Py_DECREF(right);
goto error;
}
int res = PyErr_GivenExceptionMatches(left, right);
Py_DECREF(right);
@ -6892,6 +6873,35 @@ import_all_from(PyThreadState *tstate, PyObject *locals, PyObject *v)
return err;
}
#define CANNOT_CATCH_MSG "catching classes that do not inherit from "\
"BaseException is not allowed"
static int
check_except_type_valid(PyThreadState *tstate, PyObject* right)
{
if (PyTuple_Check(right)) {
Py_ssize_t i, length;
length = PyTuple_GET_SIZE(right);
for (i = 0; i < length; i++) {
PyObject *exc = PyTuple_GET_ITEM(right, i);
if (!PyExceptionClass_Check(exc)) {
_PyErr_SetString(tstate, PyExc_TypeError,
CANNOT_CATCH_MSG);
return -1;
}
}
}
else {
if (!PyExceptionClass_Check(right)) {
_PyErr_SetString(tstate, PyExc_TypeError,
CANNOT_CATCH_MSG);
return -1;
}
}
return 0;
}
static int
check_args_iterable(PyThreadState *tstate, PyObject *func, PyObject *args)
{