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 -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at
https://mail.python.org/archives/list/[email protected]/message/RYUUOTWLMVYSTZW57MURAAGHACFWW4N7/
Code of Conduct: http://python.org/psf/codeofconduct/