-
-
Notifications
You must be signed in to change notification settings - Fork 2.9k
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
Overload + generic functions + union arguments = inconsistent results (wrong overload is matched?) #18321
Comments
Overload behavior is poorly specified and mypy's behavior is not clearly incorrect here; the second overload accepts any Possibly something should change here but a change to overload semantics would be tricky. I note that pyright passes all of your tests without errors. |
As Jelle mentioned, evaluation of calls to overloaded functions is currently underspecified in the Python typing spec, so mypy's behavior here is not clearly correct or incorrect. There is an effort underway to clarify the expected behavior for overloads. See this thread for details. Also, I recently presented the proposed spec in a typing meetup, which can be viewed here. If you have feedback on the proposal, please post to one of those discussion threads. If the latest version of my specification proposal were to be ratified, your code sample above would type check without error by type checkers that comply with the spec. |
Thanks for the discussion links. I'll add my original use case there. It looks like real-world examples are rare. For the sake of documenting the current state of things: I guess my example is technically incorrect behavior, insofar as it's internally inconsistent. But, the behavior won't change until the new spec is adopted. Is that right? What I mean is: if I change the overload order in my example, I get But, And the spec is complex, so mypy won't put in effort to implement some opinionated, unofficial-but-probably-correct overload handling until the new spec is agreed upon. Do I have all that right? Also, my example of type context inconsistency is very surprising. The two different inferred types don't even overlap. As a user, I can't wrap my head around this, even after trying to read the other topic-type-context issues. If this is really an expected class of error, perhaps it could be documented somewhere? |
Bug Report
If I have an
@overload
ed generic function, and call that function with a variable having union type, I get inconsistent results.To Reproduce
Expected Behavior
I expect that if the argument has type
str | list[str]
, thenmakelist(arg)
should be of typelist[str]
.Reason: the first
@overload
(def makelist(a: list[_T]) -> list[_T]: ...
) should matchlist[str]
. The second@overload
(def makelist(a: _T) -> list[_T]: ...
) should matchstr
. So in all cases of the argument's union type, the return type should belist[str]
.I also expect mypy to be consistent about expression types. Since mypy says
makelist(str_or_list_of_str)
has typelist[str | list[str]]
, thenlist_of_str: list[str] = makelist(str_or_list_of_str)
should raise an error.Actual Behavior
Your Environment
mypy 1.14.0 (compiled: yes)
mypy
pyproject.toml
:Python 3.10.12
If I had to guess, it seems like mypy is wrongly matching my
str | list[str]
argument to the broad overload (def makelist(a: _T) -> list[_T]: ...
). But I don't understand why it's not consistent.#17331 also involves overloads and generics. Perhaps it's related.
The text was updated successfully, but these errors were encountered: