First, let me state that I am in favour of the proposal (although still
mildle prefer the ":=" spelling).
On 17/06/2022 13:33, Chris Angelico wrote:
On Fri, 17 Jun 2022 at 22:14, Steven D'Aprano <st...@pearwood.info> wrote:
If we have:
```
items = ['spam', 'eggs']
def frob(n=>len(items), items=[]):
print(n)
```
we cannot even tell whether `frob()` will print 0 or 2 or raise an
exception.
It will either print 0 or raise UnboundLocalError. There is no
circumstance in which it will legally print 2.
Under the PEP though, this behaviour is underspecified. The PEP
describes this case as implementation dependent. Any of the following
behaviours would be legal when `frob()` is called:
* n=>len(items) evaluates the parameter `items`, *after* it gets
bound to the default of [], and so n=0 (that is, it has the same
semantics as the status quo);
Yes, this is legal.
* n=>len(items) evaluates the parameter `items`, but it isn't bound
to a value yet (because `items` occurs to the right of n), and so
evaluating the default raises (presumably) UnboundLocalError;
Yes, this is legal.
* n=>len(items) evaluates the variable items from the surrounding scope,
and so evaluates to n=2; if no such variable exists, it will presumably
raise NameError.
No, this makes no sense whatsoever. In Python, a parameter is
(effectively) assigned to within the function, and therefore *any*
reference to it *must* refer to the local, not to any surrounding
scope. Late-bound defaults do not change this fundamental.
I understand this is unambiguous, but it is nonetheless potentially
confusing: normal, immediate-evaluation arguments do, of course, have
access to enclosing scope, and so one might be led to believe that this
is still possible.
With the behaviour unspecified, we can't predict whether the above
frob() example is legal or what it will do if it is. It could vary not
only between CPython and other Pythons, but from one version of CPython
and another.
That is correct. This issue ONLY happens if a late-bound default
refers to an early-bound argument that comes to the right of it in the
argument list, and the ONLY possible results are UnboundLocalError and
getting the value.
Is there a *reason* why you are leaving this unspecified? To put it more
baldly, is there any reason (e.g., difficulty of parsing?) why allowing
these "forward" references should *not* be allowed? It seems that
"n=>len(items), items=[]" might be an important use case.
Andrew
_______________________________________________
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/TJSC55W4PUBNNOVVEUQHH5YMEWGPAP4S/
Code of Conduct: http://python.org/psf/codeofconduct/