Quantcast
Channel: Active questions tagged python - Stack Overflow
Viewing all articles
Browse latest Browse all 23305

Why aren't exceptions caught with one-liner while statement?

$
0
0

I have a code with a one-liner while and a try-except statement which behaves weirdly.

This prints 'a' on Ctrl+C:

try:    while True:        passexcept KeyboardInterrupt:    print("a")

and this too:

try:    i = 0    while True: passexcept KeyboardInterrupt:    print("a")

but this doesn't, and it throws a traceback:

try:    while True: passexcept KeyboardInterrupt:    print("a")

and neither does this code:

try:    while True: pass    i = 0except KeyboardInterrupt:    print("a")

Addition some additional details.

In 3.11, the instruction JUMP_BACKWARD was added and seems invloved with this issue see: Disassembler for Python bytecode

In 3.12 when the code in the first and the 3rd blocks are disassembled the results are:

Cannot be caught:

  0           0 RESUME                   0  2           2 NOP  3     >>    4 JUMP_BACKWARD            1 (to 4)>>    6 PUSH_EXC_INFO  4           8 LOAD_NAME                0 (KeyboardInterrupt)             10 CHECK_EXC_MATCH             12 POP_JUMP_IF_FALSE       11 (to 36)             14 POP_TOP  5          16 PUSH_NULL             18 LOAD_NAME                1 (print)             20 LOAD_CONST               1 ('a')             22 CALL                     1             30 POP_TOP             32 POP_EXCEPT             34 RETURN_CONST             2 (None)  4     >>   36 RERAISE                  0>>   38 COPY                     3             40 POP_EXCEPT             42 RERAISE                  1ExceptionTable:  4 to 4 -> 6 [0]  6 to 30 -> 38 [1] lasti  36 to 36 -> 38 [1] lastiNone

Can be caught:

  0           0 RESUME                   0  2           2 NOP  3           4 NOP  4     >>    6 NOP  3           8 JUMP_BACKWARD            2 (to 6)>>   10 PUSH_EXC_INFO  5          12 LOAD_NAME                0 (KeyboardInterrupt)             14 CHECK_EXC_MATCH             16 POP_JUMP_IF_FALSE       11 (to 40)             18 POP_TOP  6          20 PUSH_NULL             22 LOAD_NAME                1 (print)             24 LOAD_CONST               1 ('a')             26 CALL                     1             34 POP_TOP             36 POP_EXCEPT             38 RETURN_CONST             2 (None)  5     >>   40 RERAISE                  0>>   42 COPY                     3             44 POP_EXCEPT             46 RERAISE                  1ExceptionTable:  4 to 8 -> 10 [0]  10 to 34 -> 42 [1] lasti  40 to 40 -> 42 [1] lastiNone

The main differences that jump out are the two additional NOP and the different targets for JUMP_BACKWARD.

Note: the exception really cannot be caught as this will also throw the exception in 3.12

try:    try:        while True: pass    except KeyboardInterrupt:        print("a")except Exception:    print("b")

Viewing all articles
Browse latest Browse all 23305

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>