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: Concatenating a tuple to a list
Type: Stage:
Components: Interpreter Core Versions: Python 2.3
process
Status: closed Resolution: wont fix
Dependencies: Superseder:
Assigned To: Nosy List: dgrassi, loewis, rhettinger, tim.peters
Priority: normal Keywords:

Created on 2002-06-30 00:18 by dgrassi, last changed 2022-04-10 16:05 by admin. This issue is now closed.

Files
File name Uploaded Description Edit
concat.diff rhettinger, 2002-06-30 17:30 Patch to list and tuple with revised test output
Messages (12)
msg11387 - (view) Author: Dan Grassi (dgrassi) Date: 2002-06-30 00:18
"a=a+b" is not the same as "a+=b" if a is a list and b is a tuple.  See the code below.

This has been tested on 2.2.1 MacPython, 2.2 MachoPython and 2.2 Python on an Alpha.

Augmented assignment (+=) with a list on the LHS allows a tuple on the RHS.  Standard assignment does not.

This seems intuitively wrong.

--- test code ---
a=[1]
b=(2,)

print 1,type(a), a
print 1,type(b), b
c=a+b

print 2,type(a), a
print 2,type(b), b
a=a+b

print 3,type(a), a
print 3,type(b), b
a+=b

print 4,type(a), a
print 4,type(b), b

Below is the execution results of the above:

>>>
>>> a=[1]
>>> b=(2,)
>>>
>>> print 1,type(a), a
1 <type 'list'> [1]
>>> print 1,type(b), b
1 <type 'tuple'> (2,)
>>> c=a+b
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
TypeError: can only concatenate list (not "tuple") to list
>>>
>>> print 2,type(a), a
2 <type 'list'> [1]
>>> print 2,type(b), b
2 <type 'tuple'> (2,)
>>> a=a+b
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
TypeError: can only concatenate list (not "tuple") to list
>>>
>>> print 3,type(a), a
3 <type 'list'> [1]
>>> print 3,type(b), b
3 <type 'tuple'> (2,)
>>> a+=b
>>>
>>> print 4,type(a), a
4 <type 'list'> [1, 2]
>>> print 4,type(b), b
4 <type 'tuple'> (2,)
>>>
msg11388 - (view) Author: Raymond Hettinger (rhettinger) * (Python committer) Date: 2002-06-30 16:35
Logged In: YES 
user_id=80475

Confirmed.  The behavior of list_inplace_concat diverged 
from list_concat.

See attached patch. Recommend applying to Py2.3 only 
since inconsistency isn't a bug.
msg11389 - (view) Author: Martin v. Löwis (loewis) * (Python committer) Date: 2002-06-30 18:43
Logged In: YES 
user_id=21627

I'm not so sure that the current += behaviour is desirable.
It means that

a=[1]
a+="hallo"
a+={1:2}

is possible, which should be a TypeError, IMO.
msg11390 - (view) Author: Raymond Hettinger (rhettinger) * (Python committer) Date: 2002-06-30 19:00
Logged In: YES 
user_id=80475

Agreed. My first instinct was to restrict list_inplace_concat
() rather than liberalize list_concat(); however, it is already 
out in the wild and code may be relying on it.

One change or the other should be made since the docs 
promise that 'a op= b'  is equivalent to 'a = a op b' unless 
specifically overriden or when get/set attr is used to 
access 'a'.

Your example highlights the weirdness that can ensue; 
however, I think we already started down that road when 
everything was made iterable and, therefore, substitutable 
into weird combinations:

>>> zip([1], 'hallo', {1:2})
[(1, 'h', 1)]
msg11391 - (view) Author: Tim Peters (tim.peters) * (Python committer) Date: 2002-06-30 19:04
Logged In: YES 
user_id=31435

This is all intentional.  Lists choose to implement

list += whatever

as a synonym for

list.extend(whatever)

and whatever can be any iterable object in both.  It's A 
Feature that mutable objects can choose to do something 
different for += than for +.

Trying to make tuples do this too is a bad idea -- there is 
no tuple.extend(), and there can't be because tuples are 
immutable.

Lists and tuples differ here.  If they were the same thing, 
there wouldn't be much point to having both <wink>.

I recommend closing as WontFix, although it's quite 
possible the docs could be improved (haven't looked).
msg11392 - (view) Author: Raymond Hettinger (rhettinger) * (Python committer) Date: 2002-06-30 19:08
Logged In: YES 
user_id=80475

One other thought -- list.__add__ 's  behavior should 
correspond closely to list.extend():

>>> a = [1]
>>> a.extend((2,3))
>>> a.extend({4:5})
>>> a
[1, 2, 3, 4]
msg11393 - (view) Author: Tim Peters (tim.peters) * (Python committer) Date: 2002-06-30 19:25
Logged In: YES 
user_id=31435

The intent was that list.__iadd__ correspond exactly to 
list.extend().  There's no need to hypergeneralize 
list.__add__() too:  it's a feature that people who don't 
want to get surprised by Martin-like examples can avoid 
them by using plain + for lists.
msg11394 - (view) Author: Tim Peters (tim.peters) * (Python committer) Date: 2002-06-30 19:31
Logged In: YES 
user_id=31435

Dueling edits.
msg11395 - (view) Author: Raymond Hettinger (rhettinger) * (Python committer) Date: 2002-06-30 19:37
Logged In: YES 
user_id=80475

I have zero emotional attachment to this. Do whatever you 
think best: accept it, close it, or assign to GvR to get a 
pronouncement for alltime.
msg11396 - (view) Author: Raymond Hettinger (rhettinger) * (Python committer) Date: 2002-06-30 19:42
Logged In: YES 
user_id=80475

GvR,  please pronounce.
1. liberalize list_concat to match list_inplace_concat,
2. restrict list_inplace_concat to match list_concat, or
3. declare it fine the way it is.

While you're at it, pronounce for tuples also.  Timbot 
makes a good argument that they should be left alone.
msg11397 - (view) Author: Martin v. Löwis (loewis) * (Python committer) Date: 2002-06-30 21:20
Logged In: YES 
user_id=21627

I can follow Tim's view that += matches extend, and I have
to accept that extend allows arbitrary sequences. At the
same time, I think the proposed patch is wrong: Why should
[]+() return a list and not a tuple? 

So I propose to close this as "Won't fix". If Raymond and
Dan can agree, we don't need a pronouncement.
msg11398 - (view) Author: Raymond Hettinger (rhettinger) * (Python committer) Date: 2002-06-30 21:32
Logged In: YES 
user_id=80475

Done.
History
Date User Action Args
2022-04-10 16:05:28adminsetgithub: 36827
2002-06-30 00:18:32dgrassicreate