[Python-ideas] Why does += trigger UnboundLocalError?

Paul Moore p.f.moore at gmail.com
Wed Jun 1 10:51:33 CEST 2011

On 1 June 2011 09:26, Carl M. Johnson <cmjohnson.mailinglist at gmail.com> wrote:
> I don't think that's a counterexample to the point I'm trying to make. We
> all agree that if there's an x= somewhere in the function body, then we have
> to treat the variable as a local. The only possible way around that would be
> to solve the halting problem in order to figure out if a particular line of
> code will be reached or not. Agreed, sure, we have to treat the LHS of = as
> a local. But += is fundamentally different. You cannot have a += statement
> unless somewhere out there there is a matching = statement. It cannot exist
> independently. It never works on its own. So, if there is a += statement in
> the function body and there isn't an = statement in the function body it
> cannot work. Ever. All function bodies that have a += but no corresponding =
> or nonlocal are, as of today, broken code. So, if we were to change Python
> to make += not cause a variable to become a local, it wouldn't change how
> any (working) Python code today functions (it might causes some tests to
> change if they were counting on the error). This would be a completely
> backwards compatible change.
> Or am I missing something? Is there any scenario where you can get away with
> using += without = or nonlocal? I guess you could do something with
> locals().update or the stackframe, but my understanding is that those hacks
> don't count for language purposes.

The place to start here is section 4.1 of the language reference
(Naming and Binding). Specifically, "A scope defines the visibility of
a name within a block. If a local variable is defined in a block, its
scope includes that block." Your modification of augmented assignment
implies that a block can contain 2 different scopes - consider

x = 1
def f():
    # The next statement uses the global x
    x += 1
    x = 2
    # From here, you have a local x

That fundamentally changes the language semantics.

If you want to push this change, I'd suggest you start by proposing a
change to the language reference section I mentioned above to define
your proposed new scoping rules. In my view, that would be
sufficiently hard that it'd kill this proposal, but if you can manage
to do it, then you may have a chance to get your change accepted.


More information about the Python-ideas mailing list