
The current syntax for Callable types is unwieldy, particularly when extended to include varargs and keyword args as in http://mypy.readthedocs.io/en/latest/kinds_of_types.html# extended-callable-types. Why not introduce a signature literal? Proposed syntax:
return_annotation=str ) Compare the above to their equivalents using Callable (and the experimental extension to Mypy):
The proposed signature literal syntax is shorter, just as clear and imo nicer to read. Here is what it looks like in annotations: from typing import TypeVar, Callable
Initial thoughts: - () -> is ugly, but the -> would be necessary to distinguish it from the empty tuple (). Actually, it can be difficult to tell the difference between the proposed signature literals and tuples, especially for long signatures with no annotations or defaults. An alternative would be to prefix the arguments with an @ or other uncommon symbol (maybe &). () -> becomes @(), and it is clear from the start that you're reading a signature. - Supposing the syntax for function definitions was changed to match the proposed signature literals, one could make something like the following possible:
Where __call_signature__ is a magic name that evaluates to an inspect.BoundArguments instance representing the signature of the function call. I'm not sure why you'd want functions with positional-only arguments, but now you could have them. - You could further extend the function definition syntax to allow an expression that evaluates to a signature instead of a literal
Again, not sure how useful this would be.

On 29 August 2017 at 18:58, Blaine Rogers <blaine.w.rogers@gmail.com> wrote:
While a more concise spelling for that is desirable, it doesn't need to be a literal, as it can be handled by updating the Callable item lookup to accept a string literal that static type checkers know how to parse. The standard library already contains a runtime introspection variant of this to pass function signature details from Argument Clinic up to inspect.Signature as __text_signature__ attributes: https://github.com/python/cpython/blob/master/Lib/inspect.py#L1938 The main reason "create signature object from text string" isn't a public API yet is because it includes support for positional-only and variable signatures that aren't supported by pure Python function definitions (while https://www.python.org/dev/peps/pep-0457/ covers the details of how that works, my recollection is that Guido was wary of accepting an approved syntax in the absence of actual syntactic support for them in function definitions) from inspect import Signature, _signature_fromstr def str_signature(sig): parsed_sig = _signature_fromstr(Signature, (lambda: None), sig) for param in parsed_sig.parameters.values(): print("{}: {}".format(param, param.kind.name)) >>> str_signature("(a, b, /, c, d)") a: POSITIONAL_ONLY b: POSITIONAL_ONLY c: POSITIONAL_OR_KEYWORD d: POSITIONAL_OR_KEYWORD Using PEP 457 syntax and a string literal, the MyPy extended callable syntax would look like: func(__a: int, # This convention is for nameless arguments b: int, c: int = 0, *args: int, d: int, e: int = 0, **kwargs: int) -> int: ... F = Callable[ """( a: int, /, b: int, c: int = 0, *args: int, d: int, e: int = 0, **kwargs: int )""", int] Ideally, the runtime implementation of that would *skip* parsing the signature, and instead just keep the string around for on-demand parsing. Cheers, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia

On Tue, Aug 29, 2017 at 1:06 PM, Nick Coghlan <ncoghlan@gmail.com> wrote:
How about: def func(a: int, b: str) -> float: ... ? ;-) —Koos
-- + Koos Zevenhoven + http://twitter.com/k7hoven +

Hi Blaine, A similar idea has been discussed at the typing tracker, see https://github.com/python/typing/issues/239, but finally we went with the current syntax. It has several advantages such as: * It does not require a new syntax, i.e. can be backported to older Python versions * Possibility to define generic aliases without too much metaclass magic * Easier to search and ask questions on stackoverflow etc. In general, there is quite high bar to modify Python syntax, so that if there other options are available they will be preferred. -- Ivan

On 29 August 2017 at 18:58, Blaine Rogers <blaine.w.rogers@gmail.com> wrote:
While a more concise spelling for that is desirable, it doesn't need to be a literal, as it can be handled by updating the Callable item lookup to accept a string literal that static type checkers know how to parse. The standard library already contains a runtime introspection variant of this to pass function signature details from Argument Clinic up to inspect.Signature as __text_signature__ attributes: https://github.com/python/cpython/blob/master/Lib/inspect.py#L1938 The main reason "create signature object from text string" isn't a public API yet is because it includes support for positional-only and variable signatures that aren't supported by pure Python function definitions (while https://www.python.org/dev/peps/pep-0457/ covers the details of how that works, my recollection is that Guido was wary of accepting an approved syntax in the absence of actual syntactic support for them in function definitions) from inspect import Signature, _signature_fromstr def str_signature(sig): parsed_sig = _signature_fromstr(Signature, (lambda: None), sig) for param in parsed_sig.parameters.values(): print("{}: {}".format(param, param.kind.name)) >>> str_signature("(a, b, /, c, d)") a: POSITIONAL_ONLY b: POSITIONAL_ONLY c: POSITIONAL_OR_KEYWORD d: POSITIONAL_OR_KEYWORD Using PEP 457 syntax and a string literal, the MyPy extended callable syntax would look like: func(__a: int, # This convention is for nameless arguments b: int, c: int = 0, *args: int, d: int, e: int = 0, **kwargs: int) -> int: ... F = Callable[ """( a: int, /, b: int, c: int = 0, *args: int, d: int, e: int = 0, **kwargs: int )""", int] Ideally, the runtime implementation of that would *skip* parsing the signature, and instead just keep the string around for on-demand parsing. Cheers, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia

On Tue, Aug 29, 2017 at 1:06 PM, Nick Coghlan <ncoghlan@gmail.com> wrote:
How about: def func(a: int, b: str) -> float: ... ? ;-) —Koos
-- + Koos Zevenhoven + http://twitter.com/k7hoven +

Hi Blaine, A similar idea has been discussed at the typing tracker, see https://github.com/python/typing/issues/239, but finally we went with the current syntax. It has several advantages such as: * It does not require a new syntax, i.e. can be backported to older Python versions * Possibility to define generic aliases without too much metaclass magic * Easier to search and ask questions on stackoverflow etc. In general, there is quite high bar to modify Python syntax, so that if there other options are available they will be preferred. -- Ivan
participants (4)
-
Blaine Rogers
-
Ivan Levkivskyi
-
Koos Zevenhoven
-
Nick Coghlan