Steve Stagg <[email protected]> added the comment:
I re-read the change that introduced this, and the situation is slightly more
complex.
While the wording is understandably slightly ambiguous, the change talks about
the following example:
if a:
pass
else:
<do stuff>
In this scenario, the compiler is trying to eliminate the <pass> block, because
it's redundant, and this seems totally fine to me. The condition is still
evaluated, but it's changing how the empty branch is handled.
Taking the example given in the ticket:
```
while True:
if a:
pass
else:
break
```
Before the change, the DIS is:
2 0 NOP
3 >> 2 LOAD_NAME 0 (a)
4 POP_JUMP_IF_FALSE 10
4 6 JUMP_FORWARD 0 (to 8)
2 >> 8 JUMP_ABSOLUTE 2
6 >> 10 LOAD_CONST 1 (None)
12 RETURN_VALUE
2 14 LOAD_CONST 1 (None)
16 RETURN_VALUE
After the change, the DIS is:
2 0 NOP
3 >> 2 LOAD_NAME 0 (a)
4 POP_JUMP_IF_FALSE 10
4 6 NOP
2 8 JUMP_ABSOLUTE 2
6 >> 10 LOAD_CONST 1 (None)
12 RETURN_VALUE
2 14 LOAD_CONST 1 (None)
16 RETURN_VALUE
Point being, the POP_JUMP_IF_FALSE is still invoked in the intended scenario,
just some jumps are removed (OmG asserts this is faster).
So, If we test the simple case on MASTER, the following code still does the
'right thing'(tm) by evaluating bool(a):
```
class A:
def __bool__(self):
print("BOOL")
return False
a = A()
if a:
pass
```
prints "BOOL"
It seems like the issue is encountered when the "if" statement is mixed with
(some other control flow scenarios, for example) exception handling:
```
class A:
def __bool__(self):
print("BOOL")
return False
a = A()
try:
if a:
pass
except:
raise
``
prints nothing
So, ignoring the larger discussion about if it's allowed to elide bool calls
etc, this feels like an unintended side-effect of an otherwise non-contentious
branch optimization, and we should either really understand the situation
in-depth (all possible situations where this might happen), or just treat this
as a bug and fix ti
----------
title: Is it legal to eliminate tests of a value, when that test has no effect
on control flow? -> Inconsistent elimination of empty blocks by optimizer
causes __bool__calls to be skipped in some exception handling scenarios
_______________________________________
Python tracker <[email protected]>
<https://bugs.python.org/issue42899>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe:
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com