That's a fair criticism -- Protocols are usable for this, but the syntax is hardly the most intuitive, and most people would never think of this approach.
I guess the alternative would be to duplicate the full syntax allowed in the parameter list of a 'def' statement (with some tweaks perhaps), so the following would all be valid types: (x: float, method: int|None = None) -> str (*args: int, **kwds: int) -> int (a: int, b: int, /) -> int As for tweaks, maybe we can change things so that (int, int) -> int is equivalent to the latter (since this is presumably still a very common case). The rule would be something like "if there's no /, a / is assumed at the end", and also "in positional args, the syntax is [name ':'] type_expr ['=' default_expr]." Gotta go, On Sun, Nov 29, 2020 at 12:02 AM Andrew Svetlov <andrew.svet...@gmail.com> wrote: > On Sun, Nov 29, 2020 at 1:49 AM Guido van Rossum <gu...@python.org> wrote: > >> On Sat, Nov 28, 2020 at 9:32 AM Andrew Svetlov <andrew.svet...@gmail.com> >> wrote: >> >>> I would see support of all argument kinds support in any proposal for a >>> new callable: positional only args, named args, keyword-only, *args and >>> **kwargs. >>> The exact notation in probably less important than missing functionality. >>> >> >> Hm, but using Protocol you can already express every callable type. We >> could duplicate all of the complexity of 'def' parameter lists into the >> type notation, but it would be very complex. So this requirement is at >> least debatable (I'm not actually sure how I feel about it). >> >> > > Don't get me wrong please. I'm not the typing system developer (while use > typing every day in my code). > You can consider this email as end-user feedback. > > I have a lot of code that uses `Callable[]` annotation; it is a natural > way of annotating any callable, isn't it. > Sometimes `Callable` doesn't work. For example, I cannot annotate a > function that accepts a keyword-only argument. > > Sure, I can use Protocol but it doesn't feel natural and requires more > code lines, especially if the Protocol is used once or twice. > Also, Protocol adds `self` to methods which looks at least confusing when > I annotate plain callables which naturally don't belong to any class: > > class MyFunc(typing.Protocol): > def __call__(self, /, arg: int) -> str: ... > > Moreover, I recall a pull request to only of my libraries that had > something similar to: > > class MyProto(typing.Protocol): > def __call__(self_, /, self: Class, arg: int) -> str: ... > > The protocol actually had two 'self': one fake self for protocol itself > and another one if the *real* self. > The PR was refactored to use a more *natural* style but my first reaction > was eyeballs :) > > The last thing that is unclear for me is mixing protocols with ParamSpec > from PEP-612. > > Sure, I can live with all the mentioned limitations and learn all the > required tricks if we have a consensus that Callable should operate with > positional unnamed arguments only; but allowing to write such things in a > manner similar to that Python supports for function definitions already > makes life easier. > > -- > Thanks, > Andrew Svetlov > -- --Guido van Rossum (python.org/~guido) *Pronouns: he/him **(why is my pronoun here?)* <http://feministing.com/2015/02/03/how-using-they-as-a-singular-pronoun-can-change-the-world/>
_______________________________________________ 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/EAJUMPNL5DGZNHRNCGXXOD7NS3UFRWX7/ Code of Conduct: http://python.org/psf/codeofconduct/