On Tue, 26 Oct 2021, Ricky Teachey wrote:
At bottom I guess I'd describe the problem this way: with most APIs, there is a
way to PASS SOMETHING that says "give me the default". With this proposed API,
we
don't have that; the only want to say "give me the default" is to NOT pass
something.
I don't KNOW if that's a problem, it just feels like one.
I agree that it's annoying, but it's actually an existing problem with
early-bound defaults too. Consider:
```
def f(eggs = [], spam = {}): ...
```
There isn't an easy way to get the defaults for the arguments, because they're
not just *any* `[]` or `{}`, they're a specific list and dict. So if you want
to specify a value for the second argument but not the first, you'd need to do
one of the following:
```
f(spam = {'more'})
f(f.__defaults__[0], {'more'})
```
The former would work just as well with PEP 671.
The latter depends on introspection, which we're still working out.
Unfortunately, even if we can get access to the code that produces the
default, we won't be able to actually call it, because it needs to be called
from the function's scope. For example, consider:
```
def g(eggs := [], spam := {}): ...
```
In this simple case, there are no dependencies, so we could do something like
this:
```
g(g.__defaults__[0](), {'more'})
```
But in general we won't be able to make this call, because we don't have the
scope until `g` gets called and its scope created...
So there is a bit of functionality loss with PEP 671, though I'm not sure it's
that big a deal.
I wonder if it would make sense to offer a "missing argument" object (builtin?
attribute of inspect.Parameter? attribute of types.FunctionType?) that
actually simulates the behavior of that argument not being passed. Let me
call it `_missing` for now. This would actually make it far easier to
accomplish "pass in the second argument but not the first", both with early-
and late-binding defaults:
```
f(_missing, {'more'})
g(_missing, {'more'})
```
I started thinking about `_missing` when thinking about how to implement
late-binding defaults. It's at least one way to do it (then the function
itself could even do the argument checks), though perhaps there are simpler
ways that avoid the ref count increments.
Erik
--
Erik Demaine | edema...@mit.edu | http://erikdemaine.org/
_______________________________________________
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/3DLKREVEG62RHDHY4KP2R6IX2PPA633F/
Code of Conduct: http://python.org/psf/codeofconduct/