Skip to content

Fix incorrect signature suggestion from dmypy suggest when type name matches imported module name #18937

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 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion mypy/suggestions.py
Original file line number Diff line number Diff line change
Expand Up @@ -837,7 +837,7 @@ def visit_instance(self, t: Instance) -> str:
if self.module:
parts = obj.split(".") # need to split the object part if it is a nested class
tree = self.graph[self.module].tree
if tree and parts[0] in tree.names:
if tree and parts[0] in tree.names and mod not in tree.names:
mod = self.module

if (mod, obj) == ("builtins", "tuple"):
Expand Down
30 changes: 30 additions & 0 deletions test-data/unit/fine-grained-suggest.test
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,36 @@ foo(B())
(baz.B) -> Tuple[foo.A, foo:A.C]
==

[case testSuggestReexportNamingNameMatchesModule1]
# suggest: foo.foo
[file foo.py]
import bar
def foo():
return bar.bar()

[file bar.py]
class bar: ... # name matches module name

[out]
() -> bar.bar

Choose a reason for hiding this comment

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

I think this is ~sorta problematic too as tools will interpret this as "I need to add from bar import bar" which will collide with the already imported bar name

Copy link
Collaborator Author

@brianschubert brianschubert Apr 17, 2025

Choose a reason for hiding this comment

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

Hmm, not sure I follow. -> bar.bar would be a correct annotation here. If a tool decides to transform that into using -> bar with from bar import bar without checking if bar conflicts with another name in the same scope, that sounds like a problem with the tool, not with the suggestion mypy is supplying, no? Would another behavior be preferable?

Choose a reason for hiding this comment

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

mypy is really the unique place where that knowledge is -- a tool just applying suggestions would have a difficult time knowing what types the symbols are

in my original issue I had suggested (translating for this example) foo:bar.bar which would be the best suggestion without needing to add an import

==

[case testSuggestReexportNamingNameMatchesModule2]
# suggest: foo.foo
[file foo.py]
import bar
import qux
def foo():
return qux.bar()

[file bar.py]
[file qux.py]
class bar: ... # name matches another module name

[out]
() -> qux.bar
==

[case testSuggestInferInit]
# suggest: foo.Foo.__init__
[file foo.py]
Expand Down