Given the following example
try:
a, b = 0, 0
for _ in range(100):
a, b = (a 1, b 1)
except KeyboardInterrupt:
assert a == b
could an AssertionError
be thrown? If so, is there a way to prevent it, i.e. to ensure that either both of a
and b
or none is updated on every iteration?
Possibly related to Is Python unpacking thread safe?
Within, the following example and corresponding opcode are given:
>>> def t(self): a,b=20,20
...
>>> dis.dis(t)
1 0 LOAD_CONST 2 ((20, 20))
3 UNPACK_SEQUENCE 2
6 STORE_FAST 1 (a)
9 STORE_FAST 2 (b)
12 LOAD_CONST 0 (None)
15 RETURN_VALUE
Since there are two separate instructions for storing a
and b
, I would expect that no guarantees can be given whether both or none of the two instructions is executed prior to a KeyboardInterrupt
.
CodePudding user response:
Your intuition is correct: while Python will handle the interrupt internally and re-expose it separately (so interrupts are not quite as fraught as they are in C), as noted in e.g. PEP 343:
Even if you write bug-free code, a
KeyboardInterrupt
exception can still cause it to exit between any two virtual machine opcodes.