On 12/1/2015 4:36 PM, Denis McMahon wrote:
On Tue, 01 Dec 2015 16:18:49 -0500, Terry Reedy wrote:

On 12/1/2015 3:32 PM, Denis McMahon wrote:
On Tue, 01 Dec 2015 03:32:31 +0000, MRAB wrote:

In the case of:

       tup[1] += [6, 7]

what it's trying to do is:

       tup[1] = tup[1].__iadd__([6, 7])

tup[1] refers to a list, and the __iadd__ method _does_ mutate it, but
then Python tries to put the result that the method returns into
tup[1].
That fails because tup itself is a tuple, which is immutable.

I think I might have found a bug:

What you found is an specific example of what MRAB said in general
above.

$ python Python 2.7.3 (default, Jun 22 2015, 19:33:41)
[GCC 4.6.3] on linux2 Type "help", "copyright", "credits" or "license"
for more information.
tup = [1,2,3],[4,5,6]
tup
([1, 2, 3], [4, 5, 6])
tup[1]
[4, 5, 6]
tup[1] += [7,8,9]
Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
TypeError: 'tuple' object does not support item assignment

The bug is trying to replace a member of a tuple.  The correct code, to
avoid the exception while extending the list, is

tup[1].extend([7,8,9])

tup[1]
[4, 5, 6, 7, 8, 9]

You snipped the important bit of my original post, which was the state of
tup after the TypeError occurred.

No I did not. The change to tup[1] right there above, after giving the correct way to make the change.

After the error,

tup[1]
[4, 5, 6, 7, 8, 9]

This is exactly what I posted.

tup
([1, 2, 3], [4, 5, 6, 7, 8, 9])

This is a repeat of the same thing and adds no new info.

The "bug" I refer to is that despite giving the TypeError, the tuple
allowed the assignment of the mutated list to replace the original list.

No it did not. As MRAB noted, the list is mutated and the attempted assignment causes an exeption. This has been discussed before more than once ever since augmented *assignment* was introduced.

>>> tup = ([],[])
>>> id(tup[1])
711662188872

>>> tup[1] += [1]
Traceback (most recent call last):
  File "<pyshell#2>", line 1, in <module>
    tup[1] += [1]
TypeError: 'tuple' object does not support item assignment
>>> tup[1]
[1]
>>> id(tup[1])
711662188872

>>> tup[1] = tup[1].extend([2])
Traceback (most recent call last):
  File "<pyshell#7>", line 1, in <module>
    tup[1] = tup[1].extend([2])
TypeError: 'tuple' object does not support item assignment
>>> tup[1]
[1, 2]
>>> id(tup[1])
711662188872

Reading the augmented assignment doc carefully should make it clear that "tup[1] += [1]" is the same as "tup[1] = tup[1].extend([2])" except that evaluation of "tup[1]" happens just once instead of twice.

--
Terry Jan Reedy

--
https://mail.python.org/mailman/listinfo/python-list

Reply via email to