Skip to content
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

Inferring constraints for callable types doesn't verify argument counts and kinds #702

Closed
JukkaL opened this issue Jun 1, 2015 · 2 comments · Fixed by #15910
Closed
Labels
bug mypy got something wrong false-positive mypy gave an error on correct code priority-1-normal topic-calls Function calls, *args, **kwargs, defaults

Comments

@JukkaL
Copy link
Collaborator

JukkaL commented Jun 1, 2015

The method mypy.constraints.ConstraintBuildervisitor.visit_callable_type is pretty broken. It assumes that there are no *args, **kwargs and that the callable types are generally compatible.

This issue may be already filed, but adding it now so that I won't forget about it.

@JukkaL JukkaL added bug mypy got something wrong priority labels Jun 1, 2015
@ddfisher
Copy link
Collaborator

ddfisher commented Mar 2, 2016

@JukkaL can you clarify with some concrete problems?

@JukkaL JukkaL removed the priority label Jun 7, 2016
@JukkaL JukkaL added priority-1-normal false-positive mypy gave an error on correct code labels May 17, 2018
@JukkaL
Copy link
Collaborator Author

JukkaL commented May 17, 2018

Here is an example that produces incorrect output (though the example isn't realistic):

from typing import TypeVar, Callable, Tuple

T = TypeVar('T')
S = TypeVar('S')

def f(x: Callable[[T, S], None]) -> Tuple[T, S]:
    pass

def g(*x: int) -> None: pass

reveal_type(f(g))  # Tuple[int, <nothing>]

The expected output is Tuple[int, int].

@AlexWaygood AlexWaygood added the topic-calls Function calls, *args, **kwargs, defaults label Apr 3, 2022
ilevkivskyi added a commit that referenced this issue Aug 21, 2023
Fixes #702 (one of the oldest open
issues)

The approach is quite simple, I essentially replicate the logic from
subtyping check, while replacing each `is_subtype()` call with
`infer_constraints()` call. Note that we don't have various options
available in `constraints.py` so I use all checks, even those that may
be skipped with some strictness flags (so we can infer as many
constraints as possible). Depending on the output of `mypy_primer` we
can try to tune this.

Note that while I was looking at subtyping code, I noticed couple
inconsistencies for ParamSpecs, I added TODOs for them (and updated some
existing TODOs). I also deleted some code that should be dead code after
my previous cleanup.

Among inconsistencies most notably, subtyping between `Parameters` uses
wrong (opposite) direction. Normally, `Parameters` entity behaves
covariantly (w.r.t. types of individual arguments) as a single big
argument, like a tuple plus a map. But then this entity appears in a
contravariant position in `Callable`. This is how we handle it in
`constraints.py`, `join.py`, `meet.py` etc. I tried to fix the
left/right order in `visit_parameters()`, but then one test failed (and
btw same test would also fail if I would try to fix variance in
`visit_instance()`). I decided to leave this for separate PR(s).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug mypy got something wrong false-positive mypy gave an error on correct code priority-1-normal topic-calls Function calls, *args, **kwargs, defaults
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants