While looking through another question, a new asker used an expression of the form:
foo in bar == baz
I started to explain how Python interprets that expression, but quickly realized I didn't actually know how Python interprets that expression. Being too lazy to look up the order of operations, I figured it had to be equivalent to either:
(foo in bar) == baz
Or:
foo in (bar == baz)
I discovered from some testing that neither of these was actually true. Digging a little further, the bytecode for the two parenthesized statements was pretty straightforward:
>>> dis(lambda foo, bar, baz:(foo in bar) == baz)
1 0 LOAD_FAST 0 (foo)
3 LOAD_FAST 1 (bar)
6 COMPARE_OP 6 (in)
9 LOAD_FAST 2 (baz)
12 COMPARE_OP 2 (==)
15 RETURN_VALUE
>>> dis(lambda foo, bar, baz:foo in (bar == baz))
1 0 LOAD_FAST 0 (foo)
3 LOAD_FAST 1 (bar)
6 LOAD_FAST 2 (baz)
9 COMPARE_OP 2 (==)
12 COMPARE_OP 6 (in)
15 RETURN_VALUE
But the bytecode for the unadorned version is much more interesting:
>>> dis(lambda foo, bar, baz:foo in bar == baz)
1 0 LOAD_FAST 0 (foo)
3 LOAD_FAST 1 (bar)
6 DUP_TOP
7 ROT_THREE
8 COMPARE_OP 6 (in)
11 JUMP_IF_FALSE_OR_POP 21
14 LOAD_FAST 2 (baz)
17 COMPARE_OP 2 (==)
20 RETURN_VALUE
>> 21 ROT_TWO
22 POP_TOP
23 RETURN_VALUE
From my rudimentary grasp of bytecode, this appears to be equivalent to:
if foo in bar:
return bar == baz
else:
return False
I'm completely at a loss as to what the purpose of this construction is. Have I stumbled across some esoteric shorthand? Is this a side effect of some other syntax?