From d9b10c47f14c77c50dc04adb2fd81a39e814c0a8 Mon Sep 17 00:00:00 2001 From: killcerr Date: Fri, 30 Jan 2026 17:14:11 +0800 Subject: [PATCH 1/6] fix #440 --- src/interpreter/ceval.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/src/interpreter/ceval.c b/src/interpreter/ceval.c index fb16e3c8..78ef3ece 100644 --- a/src/interpreter/ceval.c +++ b/src/interpreter/ceval.c @@ -1142,8 +1142,21 @@ __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())); + bool ok = 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(!py_checktype(data + i, tp_type)) goto __ERROR; + if(py_isinstance(&self->unhandled_exc, py_totype(data + i))) { + ok = true; + break; + } + } + } else + goto __ERROR; py_newbool(TOP(), ok); DISPATCH(); } From 7b733cae0a27750646f6602ad0d7f83cc12c06fd Mon Sep 17 00:00:00 2001 From: killcerr Date: Fri, 30 Jan 2026 21:16:49 +0800 Subject: [PATCH 2/6] fix #440 --- src/interpreter/ceval.c | 10 +++++----- tests/280_exception.py | 5 +++++ 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/interpreter/ceval.c b/src/interpreter/ceval.c index 78ef3ece..b1f23996 100644 --- a/src/interpreter/ceval.c +++ b/src/interpreter/ceval.c @@ -1143,9 +1143,7 @@ __NEXT_STEP: } case OP_EXCEPTION_MATCH: { bool ok = false; - if(TOP()->type == tp_type) { - ok = py_isinstance(&self->unhandled_exc, py_totype(TOP())); - } else if(TOP()->type == tp_tuple) { + 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++) { @@ -1155,8 +1153,10 @@ __NEXT_STEP: break; } } - } else - goto __ERROR; + } else { + if(!py_checktype(TOP(), tp_type)) goto __ERROR; + ok = py_isinstance(&self->unhandled_exc, py_totype(TOP())); + } py_newbool(TOP(), ok); DISPATCH(); } diff --git a/tests/280_exception.py b/tests/280_exception.py index 85828d6d..104fa4ac 100644 --- a/tests/280_exception.py +++ b/tests/280_exception.py @@ -201,6 +201,11 @@ 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 + """ # finally, only def finally_only(): From 1b2ad4cf2a50f81592fb50aad719f000f496c09d Mon Sep 17 00:00:00 2001 From: killcerr Date: Fri, 30 Jan 2026 22:08:34 +0800 Subject: [PATCH 3/6] fix #440 --- src/interpreter/ceval.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/src/interpreter/ceval.c b/src/interpreter/ceval.c index b1f23996..f5991acb 100644 --- a/src/interpreter/ceval.c +++ b/src/interpreter/ceval.c @@ -1143,19 +1143,24 @@ __NEXT_STEP: } case OP_EXCEPTION_MATCH: { bool ok = false; - if(TOP()->type == tp_tuple) { + 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(!py_checktype(data + i, tp_type)) goto __ERROR; - if(py_isinstance(&self->unhandled_exc, py_totype(data + i))) { - ok = true; + if(data[i].type != tp_type) { + py_clearexc(TOP()); + TypeError( + "catching classes that do not inherit from BaseException is not allowed"); + ok = false; break; } + ok = py_isinstance(data + i, py_totype(TOP())); } } else { - if(!py_checktype(TOP(), tp_type)) goto __ERROR; - ok = py_isinstance(&self->unhandled_exc, py_totype(TOP())); + py_clearexc(TOP()); + TypeError("catching classes that do not inherit from BaseException is not allowed"); } py_newbool(TOP(), ok); DISPATCH(); From a92557193c85a1eebd2978cc5ee7b55d22265021 Mon Sep 17 00:00:00 2001 From: killcerr Date: Fri, 30 Jan 2026 23:15:39 +0800 Subject: [PATCH 4/6] fix #440 --- src/interpreter/ceval.c | 22 +++++++++++++++------- tests/280_exception.py | 8 ++++++++ 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/src/interpreter/ceval.c b/src/interpreter/ceval.c index f5991acb..13ba5a8e 100644 --- a/src/interpreter/ceval.c +++ b/src/interpreter/ceval.c @@ -1143,23 +1143,31 @@ __NEXT_STEP: } case OP_EXCEPTION_MATCH: { 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) { - py_clearexc(TOP()); - TypeError( - "catching classes that do not inherit from BaseException is not allowed"); - ok = false; + if((data + i)->type != tp_type) { + has_invalid = true; break; } - ok = py_isinstance(data + i, py_totype(TOP())); + } + if(!has_invalid) { + for(int i = 0; i < len; i++) { + if(py_isinstance(&self->unhandled_exc, py_totype(data + i))) { + ok = true; + break; + } + } } } else { - py_clearexc(TOP()); + has_invalid = true; + } + if(has_invalid) { + py_clearexc(NULL); TypeError("catching classes that do not inherit from BaseException is not allowed"); } py_newbool(TOP(), ok); diff --git a/tests/280_exception.py b/tests/280_exception.py index 104fa4ac..2ef09218 100644 --- a/tests/280_exception.py +++ b/tests/280_exception.py @@ -206,6 +206,14 @@ try: 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: + print(e) + """ # finally, only def finally_only(): From 5ab8381471d55d3e966db4987942ec34665b44fa Mon Sep 17 00:00:00 2001 From: killcerr Date: Sat, 31 Jan 2026 00:41:20 +0800 Subject: [PATCH 5/6] fix #440 --- tests/280_exception.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/280_exception.py b/tests/280_exception.py index 2ef09218..0b12ada1 100644 --- a/tests/280_exception.py +++ b/tests/280_exception.py @@ -212,7 +212,7 @@ try: except (ZeroDivisionError, 1) as e: assert type(e) == ZeroDivisionError except Exception as e: - print(e) + assert type(e) == TypeError """ # finally, only From 2f776ae05a0f378e8f65b90a4e6d8ba622801dd5 Mon Sep 17 00:00:00 2001 From: killcerr Date: Sun, 1 Feb 2026 06:40:09 +0800 Subject: [PATCH 6/6] fix #440 --- src/interpreter/ceval.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/interpreter/ceval.c b/src/interpreter/ceval.c index 13ba5a8e..6700108e 100644 --- a/src/interpreter/ceval.c +++ b/src/interpreter/ceval.c @@ -1169,9 +1169,12 @@ __NEXT_STEP: 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(); } - py_newbool(TOP(), ok); - DISPATCH(); } case OP_HANDLE_EXCEPTION: { FrameExcInfo* info = Frame__top_exc_info(frame);