Skip to content

[ty] Exclude already-included classes in base completions#23085

Merged
charliermarsh merged 1 commit intomainfrom
charlie/c
Feb 5, 2026
Merged

[ty] Exclude already-included classes in base completions#23085
charliermarsh merged 1 commit intomainfrom
charlie/c

Conversation

@charliermarsh
Copy link
Member

Summary

Closes astral-sh/ty#2524.

@charliermarsh charliermarsh added the ty Multi-file analysis & type inference label Feb 5, 2026
@charliermarsh charliermarsh marked this pull request as ready for review February 5, 2026 07:29
@sharkdp sharkdp removed their request for review February 5, 2026 09:28
Copy link
Member

@AlexWaygood AlexWaygood left a comment

Choose a reason for hiding this comment

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

Nice, though I'm not totally sure about the auto-import filtering (would like @BurntSushi's review!)

if builder.import.is_none() && self.existing_class_bases.contains(&builder.name) {
return true;
}
// For auto-import completions, check if the qualified name matches.
Copy link
Member

Choose a reason for hiding this comment

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

For auto-import completions, we might want to do something a bit cleverer that looks to see what kind of import the completion would add...? Because an auto-import completion can result in a from mod import Bar import being added

Copy link
Member

Choose a reason for hiding this comment

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

Yeah, I agree that this isn't quite either (see above in the non-auto-import case for why that isn't quite right either for similar reasons).

But I don't think this will hide anything that it shouldn't hide? So I think it's still an improvement.

// For in-scope completions, check if the simple name matches.
if builder.import.is_none() && self.existing_class_bases.contains(&builder.name) {
return true;
}
Copy link
Member

Choose a reason for hiding this comment

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

Hmmm I'm not sure this is quite correct. e.g.,

import foo

class MyClass(foo.Bar, foo.B<CURSOR>): pass

The completions returned on foo.B<CURSOR> won't have an import attached to them (because foo is already in scope). But the name on the completions won't be qualified. And indeed, the completions returned in that case won't have a module name associated with them at all. So you'll end up searching for Bar against foo.Bar and thus not find a match.

With that said, I don't think this will hide completions that it shouldn't. I think it just won't hide some completions that it should. So this is not really making anything worse.

I think fixing this particular issue is a bigger change so I'd be okay landing with this flaw personally.

Copy link
Member Author

Choose a reason for hiding this comment

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

Documented with a test...

// This handles cases like `class Foo(mod.Bar, ...)` where we want to
// filter out auto-import suggestions for `Bar` from module `mod`.
if let Some(module_name) = builder.module_name {
let qualified = Name::new(format!("{}.{}", module_name, builder.name));
Copy link
Member

Choose a reason for hiding this comment

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

I think you can just use builder.qualified here.

if builder.import.is_none() && self.existing_class_bases.contains(&builder.name) {
return true;
}
// For auto-import completions, check if the qualified name matches.
Copy link
Member

Choose a reason for hiding this comment

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

Yeah, I agree that this isn't quite either (see above in the non-auto-import case for why that isn't quite right either for similar reasons).

But I don't think this will hide anything that it shouldn't hide? So I think it's still an improvement.

@carljm carljm removed their request for review February 5, 2026 16:48
@charliermarsh charliermarsh merged commit 74cbc7c into main Feb 5, 2026
45 checks passed
@charliermarsh charliermarsh deleted the charlie/c branch February 5, 2026 22:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ty Multi-file analysis & type inference

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[completions] Exclude duplicate class base completions

3 participants