Python Error

Can someone please tell me where to report the following:

Using the Python interactive interpreter:

    >>> eg_tuple = ([1],[2])
    >>> eg_tuple[0] += [4]
    Traceback (most recent call last):
      File "<stdin>", line 1, in ?
    TypeError: object doesn't support item assignment
    >>> eg_tuple
    ([1, 4], [2])
    >>>
I'm a little surprised that I get both the TypeError and the changed tuple.

I've been to the Python web site and tried to find whether the bug I've found is known. I can't find anything on that site, probably because I'm not a developer, I'm not registered, I don't know what to look for, and there seem to be a lot of bugs to trawl through. It also says that to report a bug ...

you must have a SourceForge account and be logged in to submit a bug report or patch
I don't want to have SourceForge account.

I went to http://www.python.org, then its link to "Python Project: bugs". Even without a SourceForge login, I see a list of the first (by various criteria) 50 bugs. Above the list there are some widgets that allow you to narrow down the list by "Category" and other criteria. I also see a "Summary keyword" search box which looks promising. I would search for the word "tuple" or "slice" or "iadd" or "__iadd__". I also would examine the "Group" "Not a Bug" in case what you have found is a carefully reasoned "feature" of the language. -- ElizabethWiethoff

Oh, joy - I've just worked out that a large amount of the non-functioning of the site has been caused by incompatabilities with my browser. KonquerorBrowser 3.1.4 using KDE 3.1.4 on SuSE 9.0, for those who are interested.

Using MozillaFirefox I've now found the bug. It's been closed as of 2005-09-28. Personally I think it's a bug, but they obviously don't agree.

Thank you for your assistance, especially Elizabeth.

You're welcome... After a little thought, the "changed" tuple doesn't surprise me. The tuple still holds the same two list objects. Adding to a list does not change its object ID. Therefore, the tuple hasn't changed. ;-) But the TypeError still does surpise me. I would certainly expect the tuple to complain if I were to try to add some more items to it. But when I access a tuple's element, I would expect Python to look to the element for its methods and exceptions. On the other hand, the example really accesses a slice of the tuple (which happens to be a single element), and it makes sense that inserting some elements into a tuple slice is a no-no. In that case, I'm surprised the list object was changed. I should search through the bug list and find out why the bug in the list is closed. -- ElizabethWiethoff

It looks like they intend the += operator (and all similar ones) to operate as "var = var + arg"; in the case of the tuple, this implies an assignment which the tuple doesn't support. The problem is that sometimes += operates via side effects (__iadd__ returns self), and other times it operates in a functional manner (__iadd__ returns new object). Here, the tuple is complain about the attempt to assign the value, even though it's the same value, and even though the value has already been modified.

In other words, this is an optimization for a common case, where the variable is assigned the new value, and the old value promptly forgotten about:

 foo = [1,2,3]
 bar = foo

foo += [4,5] print foo "[1,2,3,4,5]" print bar "[1,2,3,4,5]" print foo == bar "True" print foo is bar "True"

And no, I don't like it either. But hey, it's efficient! My opinion on the matter would be that optimizations which cause special cases should be handled internally, transparently, and therefore not hardcoded into the language spec. Optimizations which eliminate special cases can be part of the spec (i.e., scheme).

--WilliamUnderwood

Sorry, William, but I don't see what your foo bar example has to do with the original tuple problem. Would you try again, please? -- Eliz

I'm not William but I think may be I understand what he want to say. Consider the code

 foo = [1,2,3]
 bar = foo

bar is now pointing to same list as foo, so sure, any modification to list pointed by foo will be reflected in bar, too Now consider this code
 foo += [4,5]
This should be semantically equivelent to:
 foo = foo + [4,5]
And we know that '+' is not a destructive operation. So what should actually happens is that a new list is created that is a copy of foo with [4,5] appended at the end, and that list is assign to foo. In other words it should acts identical to:

 foo = 5
 bar = foo
 foo += 5  # now foo != bar

But Python's optimization is optimization that change semantic of code, I dodn't think this is nice.


This is a known Python wart.

See Point 3, the += operator


EditText of this page (last edited September 5, 2006) or FindPage with title or text search