Skip to content

Regression: overload signatures with default parameters no longer reported as overlapping #18581

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

Closed
sterliakov opened this issue Feb 1, 2025 · 3 comments
Labels
bug mypy got something wrong topic-overloads

Comments

@sterliakov
Copy link
Collaborator

Bug Report

Since 1.11.0 and up to current master mypy no longer reports overloads in the snippet below as overlapping. 1.10.1 detects the overlap correctly.

According to the recent typing spec update for overloads, this is a bug:

If two overloads can accept the same set of arguments, they are said to "partially overlap". If two overloads partially overlap, the return type of the former overload should be assignable to the return type of the latter overload. If this condition doesn't hold, it is indicative of a programming error and should be reported by type checkers.

This bisects to #17392 - this false negative was missed there. cc @ilevkivskyi

To Reproduce

https://mypy-play.net/?mypy=1.11.0&python=3.10&flags=strict&gist=9f4be4dac4c302b9d556746cdbffa251

from typing import overload

@overload
def fn(x: str = ...) -> str: ...
@overload
def fn(x: int = ...) -> int: ...
def fn(x: int | str = 0) -> int | str:
    return x

Expected Behavior

Since fn() is allowed for both signatures, they overlap, so 1.10.1 output should remain there:

main.py:4: error: Overloaded function signatures 1 and 2 overlap with incompatible return types  [overload-overlap]

Actual Behavior

Mypy accepts the snippet.

Your Environment

  • Mypy version used: 1.11.0 through current master vs 1.10.1
  • Mypy command-line flags: --strict and without
  • Mypy configuration options from mypy.ini (and other config files): n/a
  • Python version used: 3.12
@sterliakov sterliakov added bug mypy got something wrong topic-overloads labels Feb 1, 2025
@ilevkivskyi
Copy link
Member

This is not a regression but a very conscious decision. For three reasons:

First, an "unsafe overlap" is not simply when two overload variants with distinct return types can be matched with the same actual call (otherwise we would need to prohibit a lot of overloads that are currently allowed and are actually useful). We trust that the implementation reflects the order of overloads, but we flag when it is easy to "fool" mypy into inferring a type that doesn't match the runtime one, the prime (although oversimplified) example is

class B: ...
class C(B): ...

@overload
def foo(x: C) -> int: ...
@overload
def foo(x: B) -> str: ...

x: B = C()
foo(x)  # static `str`, runtime `int`

The example you show doesn't fit here, as it is very hard to fool mypy into falsely matching the second overload.

Second, what if I consider a similar example:

@overload
def fn(x: int = ..., y: int = ..., z: int = ..., option: str = ...) -> str: ...
@overload
def fn(x: int = ..., y: int = ..., z: int = ..., option: bool = ...) -> int: ...

Should we flag it as error as well? Unlike your example (where there is an easy fix), this example is very annoying to type "properly", because arguments without a default can't follow an argument with default. And people were actually complaining about this.

And last but not least, when typical users see the "unsafe overlap" error, they think "WTH do you want from me?", as it is often not obvious how to fix the error. So we try to limit this error only to cases that are known to actually cause bugs in real code.

@ilevkivskyi ilevkivskyi closed this as not planned Won't fix, can't repro, duplicate, stale Feb 1, 2025
@sterliakov
Copy link
Collaborator Author

sterliakov commented Feb 2, 2025

This is a duplicate of #6580 (well, same scenario, but reporting the opposite behavior) - do you feel like closing that one as well?

@ilevkivskyi
Copy link
Member

@sterliakov Yes, this one of those complains I mentioned above. I will close it as it is now fixed.

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-overloads
Projects
None yet
Development

No branches or pull requests

2 participants