[Python-Dev] [PEP] += on return of function call result

Jeff Epler jepler@unpythonic.net
Sat, 17 May 2003 10:21:39 -0500


I think that looking at the generated bytecode is useful.

# Running with 'python -O'
>>> def f(x): x += 1
>>> dis.dis(f)
          0 LOAD_FAST                0 (x)
          3 LOAD_CONST               1 (1)
          6 INPLACE_ADD         
          7 STORE_FAST               0 (x)    ***
         10 LOAD_CONST               0 (None)
         13 RETURN_VALUE        
>>> def g(x): x[0] += 1
>>> dis.dis(g)
          0 LOAD_GLOBAL              0 (x)
          3 LOAD_CONST               1 (0)
          6 DUP_TOPX                 2
          9 BINARY_SUBSCR       
         10 LOAD_CONST               2 (1)
         13 INPLACE_ADD         
         14 ROT_THREE           
         15 STORE_SUBSCR                      ***
         16 LOAD_CONST               0 (None)
         19 RETURN_VALUE        
>>> def h(x): x.a += 1
>>> dis.dis(h)
          0 LOAD_GLOBAL              0 (x)
          3 DUP_TOP             
          4 LOAD_ATTR                1 (a)
          7 LOAD_CONST               1 (1)
         10 INPLACE_ADD         
         11 ROT_TWO             
         12 STORE_ATTR               1 (a)    ***
         15 LOAD_CONST               0 (None)
         18 RETURN_VALUE        

In each case, there's a STORE step to the inplace statement.  In the case of the proposed
	def j(x): x() += 1
what STORE instruction would you use?

>>> [opname for opname in dis.opname if opname.startswith("STORE")]
['STORE_SLICE+0', 'STORE_SLICE+1', 'STORE_SLICE+2', 'STORE_SLICE+3',
 'STORE_SUBSCR', 'STORE_NAME', 'STORE_ATTR', 'STORE_GLOBAL', 'STORE_FAST',
 'STORE_DEREF']

If you don't want one from the list, then you're looking at substantial
changes to Python.. (and STORE_DEREF probably doesn't do anything that's
relevant to this situation, though the name sure sounds promising,
doesn't it)

Jeff