Skip to content

Allow adjacent conditionally-defined overloads #19042

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
wants to merge 4 commits into
base: master
Choose a base branch
from

Conversation

sterliakov
Copy link
Collaborator

@sterliakov sterliakov commented May 6, 2025

Fixes #19015. Fixes #17521. Side question: why do we do that extra work to show "is already defined" error instead of "implementation must come last" in the following setting?

@overload
def f2(x: A) -> A: ...
if True:
    @overload
    def f2(x: B) -> B: ...
def f2(x): ...
if True:
    #@overload  # both with and without this decorator
    def f2(x): ...  # E: Name "f2" already defined on line 17

We have to track it specially and it doesn't work when f2 is decorated, and I struggle to understand how "already defined" is better than an overload-specific message "implementation must come last".

@sterliakov
Copy link
Collaborator Author

cc @cdce8p as original author - could you have a look, please?

@sterliakov sterliakov marked this pull request as ready for review May 6, 2025 14:37

This comment has been minimized.

@sterliakov
Copy link
Collaborator Author

sterliakov commented May 6, 2025

@sterliakov sterliakov requested a review from ilevkivskyi May 29, 2025 12:34
@bzoracler
Copy link
Contributor

This looks like it should fix #17521 as well, but I'm not able to check this right now.

@sterliakov
Copy link
Collaborator Author

It does, thanks! I expected this to be too niche to run a mypy-issues scan, but that was a wrong estimate:(

This comment has been minimized.

@sterliakov sterliakov requested a review from JukkaL June 19, 2025 10:45
def spam(v: int) -> list[int]: ...

def spam(v: "int | str") -> "list[str] | list[int]":
return []
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similar to above. Actually this looks identical to ham. Was this intentional?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it was (or rather didn't matter) as the only thing I was testing here was that two adjacent conditional overloads are interpreted correctly. But your other comment raises a good point, modified accordingly.

@@ -6310,6 +6310,31 @@ reveal_type(f12(A())) # N: Revealed type is "__main__.A"

[typing fixtures/typing-medium.pyi]

[case testAdjacentConditionalOverloads]
# flags: --always-true True
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe use some other name than True, since this overlaps with the normal True, which is confusing.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done, but I'm not sure it's actually better - all surrounding tests use --always-true True, so now this one is inconsistent which might be surprising or misleading for future readers.

Copy link
Contributor

Diff from mypy_primer, showing the effect of this PR on open source code:

comtypes (https://github.com/enthought/comtypes)
- comtypes/_post_coinit/misc.py:146: error: An overloaded function outside a stub file must have an implementation  [no-overload-impl]
- comtypes/_post_coinit/misc.py:162: error: Name "CoGetClassObject" already defined on line 146  [no-redef]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
3 participants