Skip to content

Argument 1 to type_check_only has incompatible type type[S[T, *Ts]]; expected type[S[T, *Ts]] #19093

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
jorenham opened this issue May 16, 2025 · 1 comment · May be fixed by #19100
Open
Labels
bug mypy got something wrong topic-pep-646 PEP 646 (TypeVarTuple, Unpack)

Comments

@jorenham
Copy link
Contributor

jorenham commented May 16, 2025

Consider this .pyi code snippet:

from typing import Any, Generic, Self, TypeVar, TypeVarTuple, type_check_only

T = TypeVar("T")
Ts = TypeVarTuple("Ts") 

@type_check_only
class S(tuple[*Ts], Generic[T, *Ts]):
    def f(self, x: T, /) -> T: ...

When ran through mypy (checked with 1.15.0 and the master branch), the following error is reported

Argument 1 to "type_check_only" has incompatible type "type[S[T, *Ts]]"; expected "type[S[T, *Ts]]"  [arg-type]

mypy playground repro

Without the additional T type parameter, the false positive error disappears. It also disappears if I remove the tuple baseclass.
And as far as I could tell, it doesn't seem to be associated with a particular config option or cli flag.

@jorenham jorenham added the bug mypy got something wrong label May 16, 2025
@jorenham jorenham changed the title Argument 1 to "type_check_only" has incompatible type "type[S[T, *Ts]]"; expected "type[S[T, *Ts]]" Argument 1 to type_check_only has incompatible type type[S[T, *Ts]]; expected type[S[T, *Ts]] May 16, 2025
@sterliakov
Copy link
Collaborator

Amazing. mypy does not support type_check_only at all, but this bug is rather surprising - we must be doing something deeply wrong.

Here's a pdb session following quick debugging:

> /home/stas/Documents/Work/mypy/mypy/messages.py(787)incompatible_argument()
-> breakpoint()
(Pdb) arg_type
def [T, Ts] (typing.Iterable[builtins.object] =) -> tuple[Unpack[Ts`2], fallback=a.S[T`1, Unpack[Ts`2]]]
(Pdb) expected_type
def [T, Ts] (typing.Iterable[builtins.object] =) -> tuple[Unpack[Ts`2], fallback=a.S[T`1, Unpack[Ts`2]]]
(Pdb) arg_type==expected_type
True
(Pdb) up
> /home/stas/Documents/Work/mypy/mypy/checkexpr.py(2650)check_arg()
-> code = self.msg.incompatible_argument(
(Pdb) caller_type
def [T, Ts] (typing.Iterable[builtins.object] =) -> tuple[Unpack[Ts`2], fallback=a.S[T`1, Unpack[Ts`2]]]
(Pdb) callee_type
def [T, Ts] (typing.Iterable[builtins.object] =) -> tuple[Unpack[Ts`2], fallback=a.S[T`1, Unpack[Ts`2]]]
(Pdb) caller_type==callee_type
True
(Pdb) is_subtype(caller_type, callee_type, options=self.chk.options)
False
(Pdb) is_subtype(caller_type, callee_type)
False

Hm, so the type is not a subtype of itself. I suspect fixing this is_subtype behaviour may incidentally close a couple more typevartuple issues.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug mypy got something wrong topic-pep-646 PEP 646 (TypeVarTuple, Unpack)
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants