On Sun, Jan 10, 2021 at 9:39 PM Eric Traut <eric@traut.com> wrote:
My intent was that type guards require the first argument to be passed by position. I thought that was clear in the PEP since it says "the first explicit argument", but we could add the word "positional" to make it even clearer.

Please use "positional" -- it's a clear technical term. "Explicit" could be interpreted as intending to distinguish between default argument values and values passed as arguments. After all, there's nothing implicit about f(x=1) compared to f(). ;-)
If a subclass overrides a type guard and doesn't provide the `TypeGuard` return type, a type checker could choose to flag it as an error or warning, just as it could choose to flag any incompatible override. I don't consider that related to the type guard PEP.

A PEP that introduces a new type system feature should define how that feature fits into the existing framework for subtype checking. This PEP should answer the question of whether Callable[..., bool] is a subtype of Callable[..., TypeGuard[X]]. If the answer is that it depends, that's also good to mention. But I'd like an answer, because it also affects a question about overloading which I didn't bring up yet because there was a bug in pyright here. But since you fixed it, now I can pose the question:

If two overloads only differ in one parameter and that parameter's type is Callable[..., TypeGuard[X]] in one case and Callable[..., bool] in the other overload, can the return type vary between these cases? My example is
def filter(f: Callable[[T], TypeGuard[R]], it: Iterable[T]) -> Iterator[R]: ...
def filter(f: Callable[[T], bool], it: Iterable[T]) -> Iterator[T]: ...
def filter(f, it):
This intends to produce a different return type based on whether the callable is a type guard or not. E.g. given a list of objects and an is_int() *type guard* it returns Iterator[int], but with a non-type-guard function it's Iterator[object]. I would think that the subtype question is relevant to the question of whether this should work.
If a type guard definition has insufficient _parameters_, it can't be invoked with "a first explicit argument", so it won't be usable as a type guard function. I suppose that a type checker could choose to warn the user of this at the point where the function is declared. I don't plan to add any such warning in Pyright.

This I am fine with, it will just not work as a type guard.

--Guido van Rossum (python.org/~guido)