On Fri, Oct 29, 2021 at 11:22:29AM +0200, Gerrit Holl wrote:
> On Fri, 29 Oct 2021 at 11:10, Steven D'Aprano <[email protected]> wrote:
> > Obviously you need a way to indicate that a value in __defaults__ should
> > be skipped. Here's just a sketch. Given:
> >
> > def func(a='alpha', b='beta', @c=expression, d=None)
> >
> > where only c is late bound, you could have:
> >
> > __defaults__ = ('alpha', 'beta', None, None)
> > __late_defaults__ = (None, None, <code for expression>, None)
>
> Why not define an object for that?
Because then it would have to be a public, named builtin. Or at least a
public, named value, even if it's not in the builtin namespace, it would
still be accessible to coders just by introspecting the function object.
I think NotImplemented is a good sentinel to use. Its the same size as
None, and much less commonly used as a default value.
So the algorithm for fitting default values to parameters might look
like this pseudocode:
# single pass version
for parameter in parameters:
if parameter is unbound:
obj = get default for this parameter, or fail
if obj is NotImplemented:
obj = get late_bound default for this parameter, or fail
if obj is not NotImplemented:
obj = (eval obj in function namespace)
bind obj to parameter
# two pass version, that ensures all early-bound parameters
# have a value before the late-bound ones are evaluated
for parameter in parameters:
if parameter is unbound:
obj = get default for this parameter, or fail
if obj is NotImplemented:
continue
bind obj to parameter
for parameter in parameters:
if parameter is unbound:
obj = get late_bound default for this parameter, or fail
if obj is not NotImplemented:
obj = (eval obj in function namespace)
bind obj to parameter
> In this example I don't mean a fancy new delayed evaluation type such
> as has been discussed elsewhere, but just a sentinel so Python knows
> it has to look into __late_defaults__ at all (I'm probably missing
> something, and I didn't read all prior emails on this, but why
> wouldn't this type contain a reference to the code object directly,
> negating the need for __late_defaults__...?).
How would the interpreter tell the difference between a code object
which is early bound and needs to be returned directly, unexecuted, and
a code object which is late-bound and needs to be executed?
Any code object inside the function defaults can be grabbed and used as
an early default, and we'd want it to remain unevaluated.
--
Steve
_______________________________________________
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/TC7JQ6YALXTYWPTTCAECSSLDX47RFGCD/
Code of Conduct: http://python.org/psf/codeofconduct/