By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
454,526 Members | 1,618 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 454,526 IT Pros & Developers. It's quick & easy.

Is this a bug?

P: n/a
Hi,
I've hit a corner case that I can explain to myself *why* it happens, both
under python 2.3 and python 2.4, but the following inconsistency makes me
wonder if I should log it as a bug:

First the behaviour that isn't unexpected:
a=["hello"]
a = a + "world" Traceback (most recent call last):
File "<stdin>", line 1, in ?
TypeError: can only concatenate list (not "str") to list
Which is pretty what I'd expect.

However if we do this just slightly differently:
a = ["hello"]
a += "world"
a

['hello', 'w', 'o', 'r', 'l', 'd']

We get completely different behaviour. This strikes me as a bug - should I
log it as one, or is there a good reason for this behaviour?

Regards,
Michael.

Jul 19 '05 #1
Share this Question
Share on Google+
13 Replies


P: n/a
Michael Sparks wrote:
Hi,
I've hit a corner case that I can explain to myself *why* it happens, both
under python 2.3 and python 2.4, but the following inconsistency makes me
wonder if I should log it as a bug:

First the behaviour that isn't unexpected:

a=["hello"]
a = a + "world"
Traceback (most recent call last):
File "<stdin>", line 1, in ?
TypeError: can only concatenate list (not "str") to list
Which is pretty what I'd expect.

However if we do this just slightly differently:

a = ["hello"]
a += "world"
a


['hello', 'w', 'o', 'r', 'l', 'd']

We get completely different behaviour. This strikes me as a bug - should I
log it as one, or is there a good reason for this behaviour?


It's consistent with using a.extend("world") which is what the += is
sugar for.

In [1]:a = ['hello']

In [2]:a.extend("world")

In [3]:a
Out[3]:['hello', 'w', 'o', 'r', 'l', 'd']

It's a *good* thing that .extend() takes any iterable without explicit
conversion to a list. I think that it's just a minor annoyance that the
behavior passes on to +=.

--
Robert Kern
rk***@ucsd.edu

"In the fields of hell where the grass grows high
Are the graves of dreams allowed to die."
-- Richard Harter

Jul 19 '05 #2

P: n/a
when you use a = a + 'world' python sees it as an error because of
different type.

But when you use a += 'world'
python will change the right into list (because a is a list). So when
you're code become:
a += 'world' # a += list('world')

It really helpfull if you stick to use append instead of += when you
operate list

Pujo

Jul 19 '05 #3

P: n/a
On 2005-04-24, Michael Sparks <za*****@thwackety.com> wrote:
a=["hello"]
a = a + "world" Traceback (most recent call last):
File "<stdin>", line 1, in ?
TypeError: can only concatenate list (not "str") to list However if we do this just slightly differently:
a = ["hello"]
a += "world"
a

['hello', 'w', 'o', 'r', 'l', 'd']

We get completely different behaviour. This strikes me as a bug - should I
log it as one, or is there a good reason for this behaviour?


I think it's a bug regardless of the reason for the behavior:

1) It doesn't do what a reasonable user expects.

2) It doesn't do what the documentation says it will.
According to the language reference,

An augmented assignment expression like x += 1 can be
rewritten as x = x + 1 to achieve a similar, but not
exactly equal effect. In the augmented version, x is only
evaluated once.

I don't consider the two results you posted "similar".

--
Grant Edwards grante Yow! TAILFINS!!...click...
at
visi.com
Jul 19 '05 #4

P: n/a

P: n/a
"aj****@gmail.com" wrote:
when you use a = a + 'world' python sees it as an error because of
different type.

But when you use a += 'world'
python will change the right into list (because a is a list).


"changing into a list" is a bit misleadning; to bit a bit more precise,
you may want to change that to

python will treat the right as a sequence

</F>

Jul 19 '05 #6

P: n/a
Robert Kern wrote:
It's consistent with using a.extend("world") which is what the += is
sugar for.

In [1]:a = ['hello']

In [2]:a.extend("world")

In [3]:a
Out[3]:['hello', 'w', 'o', 'r', 'l', 'd']

It's a *good* thing that .extend() takes any iterable without explicit
conversion to a list. I think that it's just a minor annoyance that the
behavior passes on to +=.


mapping += to extend is a design mistake (I guess someone got a
little carried away).

</F>

Jul 19 '05 #7

P: n/a
aj****@gmail.com wrote:
when you use a = a + 'world' python sees it as an error because of
different type.

But when you use a += 'world'
python will change the right into list (because a is a list). So when
you're code become:
a += 'world' # a += list('world')

It really helpful if you stick to use append instead of += when you
operate list


This was part of a test case I expected to fail. I was surprised when it
passed. Passing caused a latent bug, which I fixed, and I'm preventing it's
re-occurrence by changing the way the test is written.

The value that was being updated is expected to be a _string_. However it
had the possibility of being a list of strings , *if* the code was not
making appropriate checks. The test was intended to detect that failure in
the code. The fact that f += foo succeeded where f = f + foo would fail
masked a bug. It was rewritten around moments after I discovered this, but
it struck me as rather odd.

Based on this comment from the language reference posted by Grant I'd
personally consider it to be a bug...

┬*┬*┬*┬*┬*┬*"An┬*augmented┬*assignment┬*expression ┬*like┬*x┬*+=┬*1┬*can┬*be
┬*┬*┬*┬*┬*┬*rewritten┬*as┬*x┬*=┬*x┬*+┬*1┬*to┬*achi eve┬*a┬*similar,┬*but┬*not
┬*┬*┬*┬*┬*┬*exactly┬*equal┬*effect.┬*In┬*the┬*augm ented┬*version,┬*x┬*is┬*only
┬*┬*┬*┬*┬*┬*evaluated┬*once."

(I don't consider one operation succeeding and other other throwing an
exception to be similar effects)

Whilst I understand the explanations given (expected them as my post
indicated), the above comment is the one that clinches it for me.

(I also agree for example that it's good that extend takes any iterable for
example, but a PITA that += maps to extend)

That said, the bug reference mentioned above was closed with the leading
comment:

"""I think Guido said if he had it to do over, += would not be
able to take any iterable. However, that behavior has been
set in stone for several years now and it would be hard to
take away."""

https://sourceforge.net/tracker/?fun...&group_id=5470

I'm now wondering whether it should be posted as a bug, if it's not likely
to be solved short of Python 3000. (ie whether I should just consider it a
wart instead... :)

(If that's really the case I'd happily consider writing a doc patch as a
warning about the behaviour)
Michael.

Jul 19 '05 #8

P: n/a
> According to the language reference,

An augmented assignment expression like x += 1 can be
rewritten as x = x + 1 to achieve a similar, but not
exactly equal effect. In the augmented version, x is only
evaluated once.

I don't consider the two results you posted "similar".


It continues
"Also, when possible, the actual operation is performed in-place, meaning
that rather than creating a new object and assigning that to the target,
the old object is modified instead. ...Similarly, with the exception of the
possible in-place behavior, the binary operation performed by augmented
assignment is the same as the normal binary operations.
"
I take the behavior observed to be the exceptional in-place behavior
referred to. But this could certainly be clearer.

Also, Lib Ref 2.3.6.4 Mutable Sequence Types could have a line added to
the table specifying the the operation 's+=x' is the same as s.extend(x).

Terry J. Reedy

Jul 19 '05 #9

P: n/a
On 2005-04-25, Terry Reedy <tj*****@udel.edu> wrote:
According to the language reference,

An augmented assignment expression like x += 1 can be
rewritten as x = x + 1 to achieve a similar, but not
exactly equal effect. In the augmented version, x is only
evaluated once.

I don't consider the two results you posted "similar".
It continues
"Also, when possible, the actual operation is performed in-place, meaning
that rather than creating a new object and assigning that to the target,
the old object is modified instead. ...Similarly, with the exception of the
possible in-place behavior, the binary operation performed by augmented
assignment is the same as the normal binary operations.
"
I take the behavior observed to be the exceptional in-place behavior
referred to.


I certainly don't see how. Strings are immutable. The old
object can't be modified in-place, so the "in-place" behavior
is moot.

In any case, the only difference is supposed to be whether a
new object is created or an existing object is modified. The
two results shouldn't be completely different as shown by the
OP.

Your quote states quite clearly that the binary operation *is
the same* whether it's spelt a = a + b or a += b. That is
simply not true for the example we're discussing.
But this could certainly be clearer.


I don't see how that statement has anything to do with the bug
at hand.

--
Grant Edwards grante Yow! Oh my GOD -- the
at SUN just fell into YANKEE
visi.com STADIUM!!
Jul 19 '05 #10

P: n/a
Grant Edwards wrote:
On 2005-04-25, Terry Reedy <tj*****@udel.edu> wrote:
According to the language reference,

An augmented assignment expression like x += 1 can be
rewritten as x = x + 1 to achieve a similar, but not
exactly equal effect. In the augmented version, x is only
evaluated once.

I don't consider the two results you posted "similar".
It continues
"Also, when possible, the actual operation is performed in-place, meaning
that rather than creating a new object and assigning that to the target,
the old object is modified instead. ...Similarly, with the exception of the
possible in-place behavior, the binary operation performed by augmented
assignment is the same as the normal binary operations.
"
I take the behavior observed to be the exceptional in-place behavior
referred to.

I certainly don't see how. Strings are immutable. The old
object can't be modified in-place, so the "in-place" behavior
is moot.


It's the left-hand-side, in this case a list, that gets modified
in-place. Whether the right-hand-side is mutable or not is irrelevant.
In any case, the only difference is supposed to be whether a
new object is created or an existing object is modified. The
two results shouldn't be completely different as shown by the
OP.

Your quote states quite clearly that the binary operation *is
the same* whether it's spelt a = a + b or a += b. That is
simply not true for the example we're discussing.


No, the quote says "with the exception of the possible in-place
behavior, the binary operation performed by augmented assignment is the
same as the normal binary operations." This is "in-place" behavior.
Badly designed "in-place" behavior, yes.
But this could certainly be clearer.


I don't see how that statement has anything to do with the bug
at hand.


It's a mistake, but it's been in the wild too long to be changed. Thus,
it should be documented.

--
Robert Kern
rk***@ucsd.edu

"In the fields of hell where the grass grows high
Are the graves of dreams allowed to die."
-- Richard Harter

Jul 19 '05 #11

P: n/a
On 2005-04-25, Robert Kern <rk***@ucsd.edu> wrote:
I certainly don't see how. Strings are immutable. The old
object can't be modified in-place, so the "in-place" behavior
is moot.
It's the left-hand-side, in this case a list, that gets modified
in-place. Whether the right-hand-side is mutable or not is irrelevant.


You're right. I had things backwards in my head.
Your quote states quite clearly that the binary operation *is
the same* whether it's spelt a = a + b or a += b. That is
simply not true for the example we're discussing.


No, the quote says "with the exception of the possible
in-place behavior, the binary operation performed by augmented
assignment is the same as the normal binary operations." This
is "in-place" behavior. Badly designed "in-place" behavior,
yes.


Right. The binary operation performed should be the same
regardless of whether it is done in place or not. In this
case, the "in-place" behavior is completely different than the
other spelling.
It's a mistake, but it's been in the wild too long to be changed. Thus,
it should be documented.


Life's like that, unfortunately.

--
Grant Edwards grante Yow! I'm RELIGIOUS!! I
at love a man with a
visi.com HAIRPIECE!! Equip me with
MISSILES!!
Jul 19 '05 #12

P: n/a
On 2005-04-24 10:52:36 -0500, "Fredrik Lundh" <fr*****@pythonware.com> said:

mapping += to extend is a design mistake (I guess someone got a
little carried away).


I agree. I think that + and += should be the same except for the target
of the assignment. But I discussed that with the Timbot a little while
ago and he disagrees.

Regards,
Matt

Jul 19 '05 #13

P: n/a
In article <ma**************************************@python.o rg>,
Fredrik Lundh <fr*****@pythonware.com> wrote:

mapping += to extend is a design mistake (I guess someone got a
little carried away).


There were two use cases that drove augmented assignment (I know you know
this -- but other people probably do not):

reallylongvariablename = reallylongvariablename + 1
hugearray = hugearray + tinyarray

The latter was particularly coming from the Numeric types. The docs
probably should clarify that augmented assignment is *NOT* necessarily
the same as ``foo = foo + bar`` when ``foo`` is a mutable type. You can
argue that you disagree with mapping ``+=`` to ``extend()``, but I don't
think it's fair for you to flatly claim that it's a design mistake.
--
Aahz (aa**@pythoncraft.com) <*> http://www.pythoncraft.com/

"It's 106 miles to Chicago. We have a full tank of gas, a half-pack of
cigarettes, it's dark, and we're wearing sunglasses." "Hit it."
Jul 19 '05 #14

This discussion thread is closed

Replies have been disabled for this discussion.