[Python-ideas] Optional parameters without default value
Yury Selivanov
yselivanov.ml at gmail.com
Fri Mar 3 10:24:00 EST 2017
TBH I think that optional parameters isn't a problem requiring new
syntax. We probably do need syntax for positional-only arguments
(since we already have them in a way), but optional parameters
can be solved easily without a new syntax.
Syntax like:
1. def a(?foo),
2. def a(foo=pass),
3. def a([foo]),
will complicate the language too much IMO.
Yury
On 2017-03-03 9:29 AM, Victor Stinner wrote:
> Since yet another sentinel singleton sounds like a dead end, I suggest
> to use [arg=value] syntax and require a default value in the
> prototype, as currently required for *optional keyword* arguments.
>
> "[...]" syntax for optional parameter is commonly used in Python
> documentation (but the exact syntax for multiple optional arguments is
> different than what I propose, see below). I already saw this syntax
> for optional parameters in C and PHP languages at least.
>
> Python prototype of the standard library and their generated signature:
>
> def bool([x=False])
> => bool([x])
>
> def bytearray([source=None], [encoding=None], errors="strict")
> => bytearray([source], [encoding], [errors])
>
> # in practice, default value of 'default' parameter (and maybe also 'key'?)
> # will more likely be a custom sentinel
> def sum(iterable, *args, [key=None], [default=None])
> => sum(iterable, *args, [key], [default])
>
> # "/" is an hypothetical marker for positional-only arguments
> def str.replace(old, new, [count=-1], /)
> => str.replace(old, new, [count], /)
>
> def pickle.dump(obj, file, [protocol=3], *, fix_imports=True)
> => pickle.dump(obj, file, [protocol], *, fix_imports=True)
>
> An alternative for generated signature of multiple optional arguments
> is "bytearray([source[, encoding[, errors]]])", but I'm not a big fan
> of nested [...], IMHO it's harder to read. And I like the idea of
> having a signature closer to the actual Python code.
>
>
> Invalid syntaxes raising SyntaxError:
>
> * no default value: "def func([x]): ..."
> * optional arguments before *args: "def func(arg, [opt=None], *args):"
>
> In practice, calling a function without an optional argument or pass
> the (private?) sentinel as the optional argument should have the same
> behaviour. Each module is free to decide how the sentinel is exposed
> or not. For example, the inspect module has 2 sentinels: _empty is
> exposed as Signature.empty and Parameter.empty, whereas _void is
> private.
>
> If I understood correctly, Argument Clinic already supports optional
> positional arguments, and so doesn't need to be changed.
>
>
> I'm not sure that it's useful for optional keyword-only arguments:
>
> def func(*, [arg=None])
> => func(*, [arg])
>
> The only difference with optional keyword-only arguments with a
> default value is the signature:
>
> def func(*, arg=None)
> => func(*, arg=None)
>
> See also the discussion on converting the bisect functions to Argument
> Clinic and issues with the generated signature:
> http://bugs.python.org/issue28754
>
> Victor
> _______________________________________________
> Python-ideas mailing list
> Python-ideas at python.org
> https://mail.python.org/mailman/listinfo/python-ideas
> Code of Conduct: http://python.org/psf/codeofconduct/
More information about the Python-ideas
mailing list