-
-
Notifications
You must be signed in to change notification settings - Fork 2.8k
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
Wrong types and crash with polymorphic Callable #10244
Labels
Comments
It no longer crashes with mypy 0.971, but type checking is still wrong. Interestingly, it can be worked around replacing class Cont(Generic[R]):
@abstractmethod
def run(self, x: X) -> R:
...
def f(c: Cont[R]) -> R:
reveal_type(c.run)
return c.run(3)
I have also noticed that revealed type is different this time. Let's add @dataclass
class Box(Generic[T]):
inner: T
@dataclass
class Cont(Generic[R]):
run: Box[Callable[[X], R]]
def f(c: Cont[R]) -> R:
reveal_type(c.run.inner)
return c.run.inner(3)
Parameter type is |
This was referenced Nov 14, 2022
ilevkivskyi
added a commit
that referenced
this issue
Nov 16, 2022
Fixes #10244 Fixes #13515 This fixes only the crash part, I am going to fix also the embarrassing type variable clash in a separate PR, since it is completely unrelated issue. The crash happens because solver can call `is_suptype()` on the constraint bounds, and those can contain `<Erased>`. Then if it is a generic callable type (e.g. `def [S] (S) -> T` when used as a context is erased to `def [S] (S) -> <Erased>`), `is_subtype()` will try unifying them, causing the crash when applying unified arguments. My fix is to simply allow subtyping between callable types that contain `<Erased>`, we anyway allow checking subtpying between all other types with `<Erased>` components. And this technically can be useful, e.g. `[T <: DerivedGen1[<Erased>], T <: DerivedGen2[<Erased>]]` will be solved as `T <: NonGenBase`. Btw this crash technically has nothing to do with dataclasses, but it looks like there is no other way in mypy to define a callable with generic callable as argument type, if I try: ```python def foo(x: Callable[[S], T]) -> T: ... ``` to repro the crash, mypy instead interprets `foo` as `def [S, T] (x: Callable[[S], T]) -> T`, i.e. the argument type is not generic. I also tried callback protocols, but they also don't repro the crash (at least I can't find a repro), because protocols use variance for subtyping, before actually checking member types.
ilevkivskyi
added a commit
that referenced
this issue
Nov 16, 2022
Addresses the non-crash part of #10244 (and similar situations). The `freshen_function_type_vars()` use in `checkmember.py` was inconsistent: * It needs to be applied to attributes too, not just methods * It needs to be a visitor, since generic callable can appear in a nested position The downsides are ~2% performance regression, and people will see more large ids in `reveal_type()` (since refreshing functions uses a global unique counter). But since this is a correctness issue that can cause really bizarre error messages, I think it is totally worth it.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Crash Report
First of all, the code that makess mypy crash:
Adding type annotation at the last line
c: Cont[str] = Cont(Box(const_two))
prevents the crash.There's another problem - mypy gets types in function
f
wrong. Herec.run.inner
returns typeR
, while mypy insists it must by int.Traceback
To Reproduce
Full source code is in the description.
Your Environment
The text was updated successfully, but these errors were encountered: