This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: += on list inside a tuple raises TypeError but succeeds anyway
Type: behavior Stage: resolved
Components: Interpreter Core Versions: Python 3.1, Python 3.2, Python 3.3, Python 2.7, Python 2.6
process
Status: closed Resolution: not a bug
Dependencies: Superseder:
Assigned To: Nosy List: daniel.urban, ncoghlan, santoso.wijaya, scgtrp, slav0nic, stutzbach
Priority: normal Keywords:

Created on 2011-03-15 22:20 by scgtrp, last changed 2022-04-11 14:57 by admin. This issue is now closed.

Messages (3)
msg131055 - (view) Author: Mike Smith (scgtrp) Date: 2011-03-15 22:20
Using += to append to a list inside a tuple raises a TypeError but succeeds in appending the value anyway:

>>> t = (1, [2, 3, 4])
>>> t[1].append(5)
>>> t[1] += [6]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'tuple' object does not support item assignment
>>> t
(1, [2, 3, 4, 5, 6])

I have reproduced this on all the Python interpreters available to me (CPython 2.6, 2.7, and 3.1).
msg131105 - (view) Author: Daniel Urban (daniel.urban) * (Python triager) Date: 2011-03-16 12:15
The reason of this behaviour is that x += 1 basically is the same as x = x.__iadd__(1).  In the tuple case: t[1] = t[1].__iadd__([6]).  The __iadd__ call mutates the list, then the tuple item assignment raises the TypeError. 

See these examples:

>>> import dis
>>> dis.dis('x += 1')
  1           0 LOAD_NAME                0 (x) 
              3 LOAD_CONST               0 (1) 
              6 INPLACE_ADD          
              7 STORE_NAME               0 (x) 
             10 LOAD_CONST               1 (None) 
             13 RETURN_VALUE         
>>> 
>>> dis.dis('t[1] += [6]')
  1           0 LOAD_NAME                0 (t) 
              3 LOAD_CONST               0 (1) 
              6 DUP_TOP_TWO          
              7 BINARY_SUBSCR        
              8 LOAD_CONST               1 (6) 
             11 BUILD_LIST               1 
             14 INPLACE_ADD          
             15 ROT_THREE            
             16 STORE_SUBSCR         
             17 LOAD_CONST               2 (None) 
             20 RETURN_VALUE
msg131130 - (view) Author: Nick Coghlan (ncoghlan) * (Python committer) Date: 2011-03-16 15:30
As Daniel noted, this behaviour is in accordance with the language definition.

It's obscure and surprising behaviour, but it isn't wrong.
History
Date User Action Args
2022-04-11 14:57:14adminsetgithub: 55771
2011-03-16 15:30:08ncoghlansetstatus: open -> closed

nosy: + ncoghlan
messages: + msg131130

resolution: not a bug
stage: test needed -> resolved
2011-03-16 12:24:32SilentGhostsetnosy: stutzbach, daniel.urban, santoso.wijaya, scgtrp, slav0nic
title: += on list inside a tuple raises TypeError but succeds anyway -> += on list inside a tuple raises TypeError but succeeds anyway
2011-03-16 12:15:45daniel.urbansetnosy: + daniel.urban
messages: + msg131105
2011-03-16 08:52:12slav0nicsetnosy: + slav0nic
2011-03-15 23:14:14santoso.wijayasetnosy: + santoso.wijaya

versions: + Python 3.3
2011-03-15 22:36:07stutzbachsetnosy: + stutzbach
stage: test needed

versions: + Python 3.2
2011-03-15 22:20:47scgtrpcreate