python / peps

Python Enhancement Proposals
https://peps.python.org
4.45k stars 1.53k forks source link

PEP 677: Callable Type Syntax #3920

Open DomoticaVirginia opened 2 months ago

DomoticaVirginia commented 2 months ago

Documentation

(A clear and concise description of the issue.) In one of your examples there seems to me to be a small oversight: from typing import Any, Callable, Concatenate, ParamSpec, TypeVar

R = TypeVar("R")
P = ParamSpec("P")

def with_retries(
    f: Callable[P, R]
) -> Callable[Concatenate[bool, P] R]:
    def wrapper(retry_once: bool, *args: P.args, **kwargs: P.kwargs) -> R:
        ...
    return wrapper

...
where -> Callable[Concatenate[bool, P] R]:
do: -> Callable[Concatenate[bool, P], R]:

Thanks very much

brianschubert commented 2 months ago

I looked through the PEP and found a few other editorial issues (e.g. a mispellled word ("deaply"->"deeply"), a repeated article ("in a a similar"), more typos in examples). Would a PR to fix these be welcome? I see from the Contributing Guide that mass fixes to minor typos in older PEPs which do not substantially impair the PEP's meaning are generally not encouraged.

There are the potentially issues that I spotted so far:

Patch ```diff --- a/peps/pep-0677.rst +++ b/peps/pep-0677.rst @@ -63,7 +63,7 @@ We can add types to this example to detect the runtime error:: func: Callable[[int], list[int]], l: list[int] ) -> list[int]: - .... + ... ... @@ -96,7 +96,7 @@ the benefits of static typing. For example, they might write this:: func: Callable[..., Any], l: list[int] ) -> list[int]: - .... + ... ... @@ -247,7 +247,7 @@ as follows:: def with_retries( f: Callable[P, R] - ) -> Callable[Concatenate[bool, P] R]: + ) -> Callable[Concatenate[bool, P], R]: def wrapper(retry_once: bool, *args: P.args, **kwargs: P.kwargs) -> R: ... return wrapper @@ -559,7 +559,7 @@ Trailing Commas Allowing trailing commas also gives autoformatters more flexibility when splitting callable types across lines, which is always legal -following standard python whitespace rules. +following standard Python whitespace rules. Disallowing ``...`` as an Argument Type @@ -588,7 +588,7 @@ We decided that there were compelling reasons to do this: bugs due to typos. - In the ``tuple`` generic type, we special-case ``...`` to mean "more of the same", e.g. a ``tuple[int, ...]`` means a tuple with - one or more integers. We do not use ``...`` in a a similar way + one or more integers. We do not use ``...`` in a similar way in callable types, so to prevent misunderstandings it makes sense to prevent this. @@ -673,7 +673,7 @@ The evaluation rules are expressed in terms of the following pseudocode:: def evaluate_callable_type( - callable_type: ast.CallableType | ast.AsyncCallableType: + callable_type: ast.CallableType | ast.AsyncCallableType ) -> CallableType: return CallableType( is_async=isinstance(callable_type, ast.AsyncCallableType), @@ -714,7 +714,7 @@ them as if they were written in terms of the following:: import itertools import typing - def get_args(t: CallableType) -> tuple[object]: + def get_args(t: CallableType) -> tuple[object, ...]: return_type_arg = ( typing.Awaitable[t.return_type] if t.is_async @@ -726,11 +726,11 @@ them as if they were written in terms of the following:: else: argument_args = (arg.annotation for arg in arguments) return ( - *arguments_args, + *argument_args, return_type_arg ) - def get_parameters(t: CallableType) -> tuple[object]: + def get_parameters(t: CallableType) -> tuple[object, ...]: out = [] for arg in get_args(t): if isinstance(arg, typing.ParamSpec): @@ -959,7 +959,7 @@ Requiring Outer Parentheses ~~~~~~~~~~~~~~~~~~~~~~~~~~~ A concern with the current proposal is readability, particularly -when callable types are used in return type position which leads to +when callable types are used in the return type position which leads to multiple top-level ``->`` tokens, for example:: def make_adder() -> (int) -> int: @@ -981,9 +981,9 @@ follow clear, but we rejected it because rather than a two-parameter callable type. - It is not very similar to function header syntax, and one of our goals was familiar syntax inspired by function headers. -- This syntax may be more readable for deaply nested callables like the one +- This syntax may be more readable for deeply nested callables like the one above, but deep nesting is not very common. Encouraging extra parentheses - around callable types in return position via a style guide would have most of + around callable types in the return position via a style guide would have most of the readability benefit without the downsides. We also considered requiring parentheses on both the parameter list and the @@ -1071,7 +1071,7 @@ that it could be used as a type:: This change would be analogous to :pep:`585` that made built in collections like ``list`` and ``dict`` usable as types, and would make imports -more convenient, but it wouldn't help readability of the types themselves +more convenient, but it wouldn't help the readability of the types themselves much. In order to reduce the number of brackets needed in complex callable @@ -1081,7 +1081,7 @@ types, it would be possible to allow tuples for the argument list:: This actually is a significant readability improvement for multi-argument functions, but the problem is that it makes callables -with one arguments, which are the most common arity, hard to +with one argument, which are the most common arity, hard to write: because ``(x)`` evaluates to ``x``, they would have to be written like ``callable[(int,), bool]``. We find this awkward. @@ -1105,7 +1105,7 @@ Alternative APIs We considered having the runtime data ``types.CallableType`` use a more structured API where there would be separate fields for ``posonlyargs`` and ``param_spec``. The current proposal was -was inspired by the ``inspect.Signature`` type. +inspired by the ``inspect.Signature`` type. We use "argument" in our field and type names, unlike "parameter" as in ``inspect.Signature``, in order to avoid confusion with ```