On 11/9/2021 9:23 AM, Steven D'Aprano wrote:
By the way, this discussion is probably better suited to the
Python-Ideas mailing list. But since we're here...

On Tue, Nov 09, 2021 at 11:37:40AM +0100, Sebastian Rittau wrote:

To me, the "natural" solution looks like this:

def foo(x=None, y): ...
[...]

Chris Angelico asked:
What would this mean, though:

foo(2)

Is that legal?

No. This would be equal to foo(x=2) (same as now), meaning the required
argument "y" is missing.

That's an odd interpretation. What you described earlier is very similar
to the calling convention of range, which conceptually looks like this:

     range([start=0,] end, [step=1])

With your example of "foo(x=None, y)" I would expect foo(2) to mean that
x gets the default and y gets the passed in argument 2, similar to the
way that range(2) works.

Implementing with *args is possible, but awkward as one must explicitly handle each of the 0, 1, 2, 3, and >3 args cases. The exceptions for the 0 and >3 cases should match those given by the normal processing, which can change from version to version.

The actual signature is range_(start_stop, stop=_NotGiven, step=1, /), as implemented in

_NotGiven = object()
def range_(start_stop, stop=_NotGiven, step=1, /):
    if stop is _NotGiven:
        start = 0
        stop = start_stop
    else:
        start = start_stop  # Stand-in for actual code.
...     return range(start, stop, step)

>>> list(range_(4))
[0, 1, 2, 3]
>>> list(range_(3,5))
[3, 4]
>>> list(range_(3,9,2))
[3, 5, 7]

The signature of Sebastian's function with honest parameter names is foo(x_or_y, required_y=_NotGiven, /). It is the 2nd argument, not the first, that is optional, as with range. If required_y is not given, than x_or_y must be y, and x is given a default that is not part of the signature because it is explicitly bound when called. If required_y *is* given, then x_or_y can be x.

The reason Python should not accept defaulted args before required args is that it would have to create sentinels, rewrite the signature to what it actually is, and write the code to bind the input arguments to the intended parameters. Very messy. Even if possible, adding code would, for instance, mess up tracing and disassembly.

--
Terry Jan Reedy

_______________________________________________
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-le...@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at 
https://mail.python.org/archives/list/python-dev@python.org/message/FP5VPBODQVAJSVXUIKBSAR4PT2ZMO24S/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to