Skip to content

Conversation

@MatthewMckee4
Copy link
Contributor

@MatthewMckee4 MatthewMckee4 commented Oct 30, 2025

Summary

Resolves astral-sh/ty#1457

We now check if we are in a situation where we are in the name of class or function definition like def f or class f. We check if the second last token is def or class.

Test Plan

Added test shown in that issue.

Also add test for situation where we have not started typing the name like def and class . My changes do not change any behavior there, but i think it is good to show we still dont provide completions there

@AlexWaygood AlexWaygood added bug Something isn't working server Related to the LSP server ty Multi-file analysis & type inference labels Oct 30, 2025
@github-actions
Copy link
Contributor

github-actions bot commented Oct 30, 2025

Diagnostic diff on typing conformance tests

No changes detected when running ty on typing conformance tests ✅

@MatthewMckee4 MatthewMckee4 changed the title No completions in definitions [ty] Don't provide completions when in class or function definition Oct 30, 2025
@github-actions
Copy link
Contributor

github-actions bot commented Oct 30, 2025

mypy_primer results

No ecosystem changes detected ✅
No memory usage changes detected ✅

@MichaReiser MichaReiser requested review from BurntSushi and removed request for AlexWaygood, carljm, dcreager and sharkdp October 30, 2025 19:41
Copy link
Member

@MichaReiser MichaReiser left a comment

Choose a reason for hiding this comment

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

Thank you

Comment on lines 216 to 218
if is_in_comment(&parsed, offset)
|| is_in_string(&parsed, offset)
|| is_in_definition_place(&parsed, offset)
Copy link
Member

Choose a reason for hiding this comment

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

Should we pull out the tokens.before()? It seems every one of those functions now searches the tokens before offset.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good idea

.len()
.checked_sub(2)
.and_then(|i| tokens.get(i))
.is_some_and(|t| matches!(t.kind(), TokenKind::Def | TokenKind::Class))
Copy link
Member

Choose a reason for hiding this comment

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

I forgot to mention this in my PR but we should probably do this too in `type .

Copy link
Contributor Author

@MatthewMckee4 MatthewMckee4 Oct 30, 2025

Choose a reason for hiding this comment

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

cool, will cover that, though i think there is a case where we can't catch it:

image

type here is just Name in the ast.

What we can catch is this:

type f<CURSOR> = int

Copy link
Contributor Author

Choose a reason for hiding this comment

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

(unless i look directly at the string, but I'm not sure if this is right or not.

Copy link
Member

Choose a reason for hiding this comment

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

Oh right, because it is a contextual keyword. I think inspecting the source would be fine here because I don't see any case where type <name> is valid.

Comment on lines 865 to 866
) || file.read_to_string(db).is_ok_and(|source| {
source[t.range().start().to_usize()..t.range().end().to_usize()] == *"type"
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This does not seem like the right approach, but i can't seem to find any other apis to use to do this.

Copy link
Member

Choose a reason for hiding this comment

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

You want something like:

if matches!(t.kind(), TokenKind::Def | TokenKind::Class | TokenKind::Type) {
	true
} else if t.kind() == TokenKind::Name {
	let source = source_text(db, file);
	
 	&source[t.range()] == "type"
} else {
	false 
}

Copy link
Contributor Author

Choose a reason for hiding this comment

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

cool, thanks

Copy link
Member

@MichaReiser MichaReiser left a comment

Choose a reason for hiding this comment

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

Sweet

@MichaReiser MichaReiser merged commit 3be3a10 into astral-sh:main Oct 30, 2025
41 checks passed
MatthewMckee4 added a commit to MatthewMckee4/ruff that referenced this pull request Oct 30, 2025
Copy link
Member

@BurntSushi BurntSushi left a comment

Choose a reason for hiding this comment

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

I realize this PR was already merged, but I wanted to leave feedback anyway.

I can address these in a follow-up PR if you don't want though. :-)

/// a string token (regular, f-string, t-string, etc).
///
/// Note that this will return `false` when positioned within an
/// interpolation block in an f-string or a t-string.
Copy link
Member

Choose a reason for hiding this comment

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

The doc comments for this function (and the one above) should be updated.

);

builder.auto_import().build().not_contains("fabs");
}
Copy link
Member

Choose a reason for hiding this comment

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

I don't think these tests need to be enabling auto_import(). That's a bit of a big hammer. You can instead add a local item in the source file and test completions on that.


/// If the tokens end with `class f` or `def f` we return true.
/// If the tokens end with `class` or `def`, we return false.
/// This is fine because we don't provide completions anyway.
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 it would be better to not repeat the implementation in the doc comment where possible. e.g., Your doc comment doesn't include type. Instead, something like, "Returns true when the tokens indicate that the definition of a new name is being introduced at the end."

dcreager added a commit that referenced this pull request Oct 31, 2025
* origin/main:
  [ty] Fix generic inference for non-dataclass inheriting from generic dataclass (#21159)
  Update etcetera to 0.11.0 (#21160)
  Fix missing diagnostics for notebooks (#21156)
  [ty] Fix tests for definition completions (#21153)
  Bump v0.14.3 (#21152)
  [ty] Don't provide completions when in class or function definition (#21146)
  [ty] Use the top materialization of classes for narrowing in class-patterns for `match` statements (#21150)
@MatthewMckee4
Copy link
Contributor Author

Thanks for the feedback, ill address this in a PR

@MatthewMckee4 MatthewMckee4 deleted the no-completions-in-definitions branch November 1, 2025 15:07
BurntSushi pushed a commit that referenced this pull request Nov 2, 2025
<!--
Thank you for contributing to Ruff/ty! To help us out with reviewing,
please consider the following:

- Does this pull request include a summary of the change? (See below.)
- Does this pull request include a descriptive title? (Please prefix
with `[ty]` for ty pull
  requests.)
- Does this pull request include references to any relevant issues?
-->

## Summary

@BurntSushi provided some feedback in #21146 so i address it here.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working server Related to the LSP server ty Multi-file analysis & type inference

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Disable auto-import completions in definition places

4 participants