On Tue, Feb 25, 2014 at 6:59 AM, Masklinn <masklinn@masklinn.net> wrote:
a = foo() a.bar()
compiles to:
0 LOAD_* 0 (foo) 3 CALL_FUNCTION 0 (0 positional, 0 keyword pair) 6 STORE_FAST 0 (a)
9 LOAD_FAST 0 (a) 12 LOAD_ATTR 1 (bar) 15 CALL_FUNCTION 0 (0 positional, 0 keyword pair) 18 POP_TOP
the pair (6, 9) is a noop and could trivially be removed (in the absence of jumps around). According to [0] a patch implementing this (although without taking care of jumps) was rejected:
Possible reason for rejection: The optimizer would have to be sure that a wasn't used anywhere else. a = foo() a.bar() a.spam() 2 0 LOAD_GLOBAL 0 (foo) 3 CALL_FUNCTION 0 (0 positional, 0 keyword pair) 6 STORE_FAST 0 (a) 3 9 LOAD_FAST 0 (a) 12 LOAD_ATTR 1 (bar) 15 CALL_FUNCTION 0 (0 positional, 0 keyword pair) 18 POP_TOP 4 19 LOAD_FAST 0 (a) 22 LOAD_ATTR 2 (spam) 25 CALL_FUNCTION 0 (0 positional, 0 keyword pair) 28 POP_TOP The subsequent LOAD_FAST of a depends on the STORE_FAST having been done. In the specific case mentioned in your link, he was looking for a RETURN_VALUE opcode, so that would be safe. (But if there really is code like he's seeing, I'd look at tidying it up on the Python source level. Just return the value directly. No need for "single exit point" in Python code.) ChrisA