diff --git a/src/interpreter/ceval.c b/src/interpreter/ceval.c index fb16e3c8..6700108e 100644 --- a/src/interpreter/ceval.c +++ b/src/interpreter/ceval.c @@ -1142,10 +1142,39 @@ __NEXT_STEP: DISPATCH(); } case OP_EXCEPTION_MATCH: { - if(!py_checktype(TOP(), tp_type)) goto __ERROR; - bool ok = py_isinstance(&self->unhandled_exc, py_totype(TOP())); - py_newbool(TOP(), ok); - DISPATCH(); + bool ok = false; + bool has_invalid = false; + if(TOP()->type == tp_type) { + ok = py_isinstance(&self->unhandled_exc, py_totype(TOP())); + } else if(TOP()->type == tp_tuple) { + int len = py_tuple_len(TOP()); + py_ObjectRef data = py_tuple_data(TOP()); + for(int i = 0; i < len; i++) { + if((data + i)->type != tp_type) { + has_invalid = true; + break; + } + } + if(!has_invalid) { + for(int i = 0; i < len; i++) { + if(py_isinstance(&self->unhandled_exc, py_totype(data + i))) { + ok = true; + break; + } + } + } + } else { + has_invalid = true; + } + if(has_invalid) { + py_clearexc(NULL); + TypeError("catching classes that do not inherit from BaseException is not allowed"); + c11_vector__pop(&frame->exc_stack); + goto __ERROR_RE_RAISE; + } else { + py_newbool(TOP(), ok); + DISPATCH(); + } } case OP_HANDLE_EXCEPTION: { FrameExcInfo* info = Frame__top_exc_info(frame); diff --git a/tests/280_exception.py b/tests/280_exception.py index 85828d6d..0b12ada1 100644 --- a/tests/280_exception.py +++ b/tests/280_exception.py @@ -201,6 +201,19 @@ for i in range(6): a.append(i) assert a == [0, 1, 3, 4, 5] +try: + result = 10 / 0 +except (ZeroDivisionError, TypeError) as e: + assert type(e) == ZeroDivisionError + +try: + try: + result = 10 / 0 + except (ZeroDivisionError, 1) as e: + assert type(e) == ZeroDivisionError +except Exception as e: + assert type(e) == TypeError + """ # finally, only def finally_only():