Hi Nathaniel! Thank you for the interest and feedback on the PEP!
they all involve referencing Ps.args and Ps.kwargs inside the function/class scope that uses Ps, while here we need to reference them right in the same args list.
I believe there actually is one instance of this kind of function in the PEP: ``` One additional form that we want to support is functions that pass only a subset of their arguments on to another function. To avoid shadowing a named or keyword only argument in the ParameterSpecification we require that the additional arguments be anonymous arguments that precede the *args and *kwargs def call_n_times( __f: Callable[TParams, None], __n: int, *args: TParams.args, **kwargs: TParams.kwargs, ) -> None: for x in range(__n); __f(*args, **kwargs) ``` I agree this isn't exactly prominent in the flow of the document. In my forthcoming draft, this is highlighted more forcefully, as it forms the basis of the `Concatenate` syntax. Note that this also introduces the constraint that the preceding parameters be positional-only. I'll get more into the details of why when answering your third question.
So even with PEP 612, we still can't type loop.call_soon. Is that correct?
This is correct, but we have a plan for handling these scenarios :). The plan for these is to introduce another kind of variable, the ListVariadic. You can see more details of the plan for these here: https://github.com/facebook/pyre-check/blob/master/docs/Variadic_Type_Variab...
def call_in_special_context(f, *args, **kwargs, special_kwarg):
This example doesn't actually pass the python parser. The rule is that nothing can come after a **kwargs parameter. However, if you consider the corrected spelling: ``` def call_in_special_context(__f: Callable[Ps, R], *args: Ps.args, special_kwarg: SomeType, **kwargs, Ps.kwargs) -> R: ``` This is explicitly banned by the PEP: "we require that the additional arguments be anonymous arguments that precede the *args and *kwargs". The rationale for this is that otherwise we could end up substituting our way into impossible callable types: in this example, if the callable passed in for `__f` also had a `special_kwarg` keyword only parameter." Consider the following example: ``` def wrapper(f: Callable[TParams, int]) -> Callable[TParams, int]: def inner(*args: TParams.args, **kwargs: TParams.args) -> int: # fails at runtime with TypeError: call_in_special_context() got multiple values for keyword argument 'special_kwarg' return call_in_special_context(f, *args, special_kwarg=42, **kwargs) return inner @wrapper def ohno(*, special_kwarg: str) -> int: return -1 ohno("A") ``` We can avoid this situation with positional-only parameters, so those are the only ones we accept. Hope that answers your questions! Best, Mark