Hi Mark,
I really like this PEP - it'll be useful to have more expressive ways of annotating decorators. The current form looks pretty good to me. A few comments:
* `typing.type_variable_operators` is quite verbose. How about just `typing.operators`?
* For user-defined generic classes using a ParamSpec, I think it would be useful to include an example of how such a class is constructed, since it wasn't obvious to me where values with the parameters_expression type would come from at runtime. Is
def __init__(self, x: Callable[P, int]): ...
and variations the only way to create such a class? Or do P.args and P.kwargs come into play in some way?
* "Inside the function, args has the type P.args, not Tuple[P.args, ...] as would be with a normal annotation (and likewise with the **kwargs)" (in the
ParamSpec semantics section). If I'm reading this correctly, it's saying that P.args represents the full type of args, Tuple and all, unlike a normal args annotation which describes just the contained type. Why is that the case? It seems like it would be better to not have this inconsistency unless it's necessary.
Also, some typos and such I noticed:
* I found the
x_int_y_str, y_int_x_str example hard to read, since the slight differences between the two foo calls are hard to spot. One way I can think of to improve this would be to make the function names shorter (maybe just x_y and y_x?) so it takes less time to spot the difference.
Best,
Rebecca