On Sat, Dec 4, 2021 at 2:34 PM Steven D'Aprano firstname.lastname@example.org wrote:
On Fri, Dec 03, 2021 at 10:40:42AM +1100, Chris Angelico wrote:
Here's what you get:
def f(lst=>, n=>len(lst)): ...
String representation, but exactly what the default is.
Excellent. And you've just proven that we can evaluate the defaults.
>>> a = '' # f.__defaults_extra__ >>> b = 'len(lst)' # f.__defaults_extra__ >>> lst = eval(a, globals()) >>> n = eval(b, globals(), dict(lst=lst)) >>> print(lst, n)  0
Worst case scenario, we can eval the string representation, and that should work for the great majority of cases that don't involve nonlocals.
Yes, those awkward cases that involve nonlocals. A pity about those.
But hey, if that's not a problem to you, then sure, go ahead, just eval it. The string is there for you to use.
But if the defaults are proper code objects, complete with a closure to capture their nonlocal environment, then we should be able to do even better and capture nonlocals as well.
Could there be odd corner cases that don't quite work? Say, like a comprehension inside a class body?
Oh well. Let's not make the perfect the enemy of the good.
Lots and lots and lots of potential problems. Consider:
def f(): a = 1 def f(b, x=>a+b): def g(): return x, a, b
Both a and b are closure variables - one because it comes from an outer scope, one because it's used in an inner scope. So to evaluate a+b, you have to look up an existing closure cell, AND construct a new closure cell.
The only way to do that is for the compiled code of a+b to exist entirely within the context of f's code object. Which means that there isn't really anything to usefully pull out and evaluate, since it can't be executed until you've set up a stack frame to call f, and once you've done that, you're basically just... calling f anyway.
If you still dispute that it's impossible, you're absolutely welcome to write your own reference implementation. I've argued this point with as much detail as I can, and short of pointing stuff out in the code, I can't do anything more. If you want to keep on saying "but of COURSE it's possible", then go ahead, prove it to me.