Exceptions raised in 'else' should run 'finally' before raising, not run 'except'

This commit is contained in:
K. Lange 2022-07-29 20:05:21 +09:00
parent 2f18ecbaa1
commit 9bd257e625
5 changed files with 30 additions and 0 deletions

View File

@ -2260,9 +2260,16 @@ _anotherExcept:
consume(TOKEN_COLON, "Expected ':' after 'else'.");
patchJump(exitJumpOffsets[0]);
firstJump = 1;
emitByte(OP_TRY_ELSE);
beginScope(state);
block(state, blockWidth, "else");
endScope(state);
if (nextJump == -1) {
/* If there were no except: blocks, we need to make sure that the
* 'try' handler goes directly to the finally, so that 'break'/'continue'
* within the 'try' does not run this 'else' step. */
patchJump(tryJump);
}
goto _anotherExcept;
} else if (match(TOKEN_FINALLY)) {
consume(TOKEN_COLON, "Expected ':' after 'finally'.");

View File

@ -111,3 +111,4 @@ SIMPLE(OP_INHERIT)
JUMP(OP_CALL_ITER,+)
JUMP(OP_JUMP_IF_TRUE_OR_POP,+)
OPERAND(OP_EXIT_LOOP, (void)0)
SIMPLE(OP_TRY_ELSE)

View File

@ -2414,6 +2414,12 @@ _finishReturn: (void)0;
krk_push(BOOLEAN_VAL(isMatch));
break;
}
case OP_TRY_ELSE: {
if (IS_HANDLER(krk_peek(0))) {
krk_currentThread.stackTop[-1] = HANDLER_VAL(OP_FILTER_EXCEPT,AS_HANDLER_TARGET(krk_peek(0)));
}
break;
}
case OP_BEGIN_FINALLY: {
if (IS_HANDLER(krk_peek(0))) {
if (AS_HANDLER_TYPE(krk_peek(0)) == OP_PUSH_TRY) {

12
test/testTryElseRaise.krk Normal file
View File

@ -0,0 +1,12 @@
try:
try:
print("good")
except:
print("bad")
else:
print('else')
raise ValueError
finally:
print('finally')
except ValueError:
print("raised ValueError as expected")

View File

@ -0,0 +1,4 @@
good
else
finally
raised ValueError as expected