On Thu, May 28, 2020 at 12:11:38PM +0200, Alex Hall wrote:

> Consider this code:
> 
> ```
> x = 1
> 
> def foo():
>     print(x)
>     x = 2
> 
> foo()
> ```
> 
> Here `print(x)` doesn't print '1', it gives `UnboundLocalError: local
> variable 'x' referenced before assignment`. It knows that `x` is meant to
> be a local and ignores the global value. That doesn't look like an
> implementation detail to me - does Jython do something different?

I never said that Python's scoping rules were implementation details.

I said that the storage mechanism of *how* local variables are stored, 
and hence whether or not writes to `locals()` are reflected in the 
local variables, is an implementation detail.

I'm too lazy to look it up right now, but I'm 99.9999999% (nine nines) 
certain that Python's execution model defines that any binding operation 
inside the function scope to an undotted name inside a function must 
make it a local, unless explicitly declared nonlocal or global.

(Even if that binding operation is unreachable code.)

Binding operations include regular assignment with `=`, imports, `for`, 
`with ... as`, `except ... as`, and `del`. I don't know about the walrus 
operator.

That means that any non-buggy compliant Python must print NameError, or 
its subclass UnboundLocalError, when calling your foo function above.

(I *think* that NameError would be acceptable, but you might have to ask 
the Steering Council to make a ruling if it's not already documented.)

However the behaviour of

    locals()['x'] = 999

inside that function is explicitly documented as subject to 
implementation differences, which is what I was talking about.


For the record, both IronPython and Jython 2.7 raise 
UnboundLocalError, but micropython just raises NameError:


$ micropython
MicroPython v1.9.4 on 2019-01-13; linux version
Use Ctrl-D to exit, Ctrl-E for paste mode
>>> x = 1
>>> def spam():
...     print(x)
...     x = 2
...
>>> spam()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 2, in spam
NameError: local variable referenced before assignment


Micropython often gets special dispensation to bend the rules, but in 
this case I don't think that it needs it. So long as any implementation 
raises a NameError, not necessarily UnboundLocalError, I think that's 
sufficient.


-- 
Steven
_______________________________________________
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/RYUUOTWLMVYSTZW57MURAAGHACFWW4N7/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to