[issue46612] Unclear behavior of += operator

2022-02-02 Thread Marek Scholle


New submission from Marek Scholle :

Hi, I ran into discussion about scoping in Python (visibility of outer 
variables in nested functions, global, nonlocal) which made me to create for 
other some showcases.

I realized there is a space for ambiguity which I extracted to this REPL:


>>> x = []
>>> def f(): x += [1]
...
>>> f()
Traceback (most recent call last):
  File "", line 1, in 
  File "", line 1, in f
UnboundLocalError: local variable 'x' referenced before assignment
>>> x = []
>>> def f(): x.append(1)
...
>>> f()
>>> x
[1]


The documentation says about `x += [1]` it is "translated" to 
`x.__iadd__([1])`. It would be interesting to know if Python actually documents 
that `x += [1]` will err with `UnboundLocalError`.

I think there is a natural argument that `x += ` should behave as an 
in-place version of `x = x + ` (where `UnboundLocalError` makes perfect 
sense), but diving into documentation it seems that `x += ` should be a 
syntax sugar for `x.__iadd__(rhs)` in which case `UnboundLocalError` should not 
happen and looks like some parser artifact.

--
components: Interpreter Core
messages: 412365
nosy: mscholle
priority: normal
severity: normal
status: open
title: Unclear behavior of += operator
type: behavior
versions: Python 3.9

___
Python tracker 
<https://bugs.python.org/issue46612>
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue46612] Unclear behavior of += operator

2022-02-02 Thread Marek Scholle


Marek Scholle  added the comment:

Thanks for pointing to reference 
https://docs.python.org/3/reference/simple_stmts.html#augmented-assignment-statements

Although I can agree it tries to point to similarity with `x = x + 1`, it says 
about how `x += [1]` is processed:

(1) evaluate the target (`x`)
(2) evaluate the expression list (`[1]`)
(3) call `+=`, which I understand dispatch `x.__iadd__([1])`

I see there is no space left for `UnboundLocalError`.

> The assignment done by augmented assignment statements is handled the same 
> way as normal assignments.

This is not a technical claim. They are not the same, and to claim "they are 
handled the same way" is strictly speaking an empty statement. For which 
definition of "same way"?

--

___
Python tracker 
<https://bugs.python.org/issue46612>
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue46612] Unclear behavior of += operator

2022-02-02 Thread Marek Scholle


Marek Scholle  added the comment:

I don't understand the comment https://bugs.python.org/issue46612#msg412374


>>> def f(): x
...
>>> f()

is OK, so x is something which can be evaluated inside nested function, it is a 
good target to be used in `x.__iadd__(iterable)`.

That 

>>> def f(): x = x + 1
...
>>> f()
Traceback (most recent call last):
  File "", line 1, in 
  File "", line 1, in f
UnboundLocalError: local variable 'x' referenced before assignment

is OK, the interpreter sees `x` as local variable (by default inner scope 
variables shadow those from outer scopes), hence the `UnboundLocalError`

--

___
Python tracker 
<https://bugs.python.org/issue46612>
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue46612] Unclear behavior of += operator

2022-02-02 Thread Marek Scholle


Marek Scholle  added the comment:

> a += b means (is closest to) a = type(a).__iadd__(a, b)

I exchanged several messages, and this is all I needed!
I propose to resolve as "Not a bug"

--

___
Python tracker 
<https://bugs.python.org/issue46612>
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com