[Python-ideas] Globalize lonely augmented assignment

Terry Reedy tjreedy at udel.edu
Sun Jun 13 02:25:37 CEST 2010

On 6/12/2010 11:43 AM, Bruce Frederiksen wrote:
> On Sat, Jun 12, 2010 at 3:10 AM, Terry Reedy<tjreedy at udel.edu>  wrote:
>> On 6/11/2010 9:18 PM, Demur Rumed wrote:
>>> I view the augmented assignment operators as different beasts.
>> Your view is one that leads to buggy code. It is wrong in that respect.
>> An augmented assignment STATEMEMT is both a STATEMENT, not an operator, and an ASSIGNMENT statement. Misunderstanding this leads to buggy code and posts on python list "why doesnt my code not work righ?"
> I am curious about these buggy code examples.  Do you have any?

Yes. Think a bit, or search the python-list archives, where I have been 
answering newbie questions and confusions for a decade.

> The standard assignment statement _binds_ the local variable.  But the
> augmented assignment only _rebinds_ it.  The augmented assignment does
> not give the variable a value if it doesn't already have one.
> I think that we all agree that if the function has an assignment to
> the variable some place else, the variable is a local variable.

And this proposal would break that simple rule.
It also would break the simple rule than one can only rebind a global or 
nonlocal name if one explicit declares them. Namespaces are complex 
enough that any simplicity is a virtue.

> So we are considering the case where no assignment to the variable
> exists within the function, but there is an augmented assignment.

This *is* an assignment, documented in 6.2.1. Augmented assignment 
statements as a subsection of 6.2. Assignment statements. There is says 
"the assignment done by augmented assignment statements is handled the 
same way as normal assignments." This proposal would add a fiddly exception.

If there is no previous assignment, it is a bug and should be flagged.

To expand on what Georg said,

x op= y

is equivalent to something like

<ref> '=' target('x')
<ref> = *<ref> iop y

where <ref> and target('x') are interpreter-level reference constructs,
'=' is internal, interpreter-level binding, and *<ref> is the Pythoh 
object <ref> references.

This proposal would break that equivalence.

It would also make the meaning of x op= y depend on what other 
statememts (other than the exceptional global/nonlocal declarations) are 
present in the same block.

x = 1
def f(y,z)
   x = y+z
   x /= 2.0

runs fine. Now during editing/refactoring, the x=y+z line is removed or 
x is change to something else. The program has a bug and an error should 
be raised. This proposal would mask the bug and have the x /= 2.0 
statement change its meaning.

Now, one can tell what global vars a function rebinds by looking for a 
global statement, which sensible programmers always put at the top of 
the function body after any doc string. (I think that someone argued 
that "well, globals can be mutated without declaration" as if 
compounding a somewhat bad thing is a good thing. As a matter style, I 
think declaring a global declaration for non-args mutated by a function, 
when possible, would also be a good thing. Or the doc string should 
mention such.)

In summary, this proposal creates several problems, all for the sake of 
a programmer who does not want to type 'global x'.


More information about the Python-ideas mailing list