On Wed, Jun 16, 2021 at 11:29 AM Jelle Zijlstra <jelle.zijlstra@gmail.com> wrote:
I would favor a shorthand where a bare name means a typed positional-only argument. That means we both get a nice shorthand (e.g., `(int, str) -> int` corresponds to `Callable[[int, str], int]`) and full power to represent all signatures (you can write `(a: int, /, b: str, *, c: int = ...) -> int` if you really need it).

El mié, 16 jun 2021 a las 11:06, Guido van Rossum (<guido@python.org>) escribió:
[...]
Additionally, what are the concerns with allowing a hybrid of named and unnamed params, ie.:

 

f: (int, str, *, foo: int = ..., **kwargs: str) -> bool


If we were to allow this, it'd be harder to give a simple rule for when the argument names can be omitted or not -- for example would we allow this?

f: (int, name: str) -> bool
This would be shorthand for a function that takes a positional-only argument of type int and a positional-or-keyword argument named "name" of type str.

But if you spell that out, you'd have to add a /, i.e.

def f(unused: int, /, name: str) -> bool: ...

I would prefer to use a simpler rule:

- Either there are *no* colons, stars, slashes or equal signs, and then it's a bunch of positional-only args given by type; example: (int, str) -> bool.

- Or the argument list follows the rules of 'def'; example: (a: int, b: str) -> bool. In this form a "bare" name represents an argument name and has the implicit type Any, like it has in function definitions. (Or Undefined, in checkers that make a distinction, like pyright.)

or this?

f: (count: int, str) -> bool

or even this?

f: (a: int, b, c: str) -> bool
These two would be illegal because a positional-only argument cannot follow a positional-or-keyword argument.

Hm, so with my "simpler" rule, those would be untyped arguments (in the first example, the argument name would be confusingly 'str' and the type 'Any'; in the second, we'd have 'b: Any').

But I honestly don't know what users would expect that to mean -- probably if the name is a known type, they'd expect it to be a type, but if it wasn't, they'd expect it to be an argument name -- but that's not a rule we can implement.

--
--Guido van Rossum (python.org/~guido)