Skip to content

Comments

[ty] Add inlay hints for call arguments#19269

Merged
MichaReiser merged 33 commits intoastral-sh:mainfrom
MatthewMckee4:function-argument-inlay-hints
Aug 12, 2025
Merged

[ty] Add inlay hints for call arguments#19269
MichaReiser merged 33 commits intoastral-sh:mainfrom
MatthewMckee4:function-argument-inlay-hints

Conversation

@MatthewMckee4
Copy link
Contributor

@MatthewMckee4 MatthewMckee4 commented Jul 10, 2025

Summary

Add function argument inlay hints.

Note that the inlay hints here have the structure {name}= instead of {name}: for rust. I think this makes more sense for python.

image

As you can see I have made lots of visibility modifiers public. I don't want to do this, but I have for an initial showcase of this feature.

If anyone can advise on a better solution (maybe some function inside the ty_python_semantic crate) that would be greatly appreciated.

Test Plan

Add tests to ty_ide/src/inlay_hints.rs.

@MatthewMckee4
Copy link
Contributor Author

Will mark this as ready for review for some initial feedback

@MatthewMckee4 MatthewMckee4 marked this pull request as ready for review July 10, 2025 18:05
@AlexWaygood AlexWaygood added server Related to the LSP server ty Multi-file analysis & type inference labels Jul 10, 2025
@github-actions
Copy link
Contributor

github-actions bot commented Jul 10, 2025

mypy_primer results

No ecosystem changes detected ✅
No memory usage changes detected ✅

@AlexWaygood AlexWaygood removed their request for review July 10, 2025 19:39
let call_ty = call.func.inferred_type(&self.model).into_callable(self.db);
if let Some(Type::Callable(callable)) = call_ty {
let first_signature = callable.signatures(self.db).into_iter().next().cloned();
if let Some(signature) = first_signature {
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 we need to match the signature here to resolve the best matching overload or it will show incorrect results for overloads

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah that makes sense, I just took the first one for initial demonstration. I'll look into to how to do that

Copy link
Member

Choose a reason for hiding this comment

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

It could make sense to take a look at the signature_help implementation which does something very similar.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Okay thank you

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 works well, but it also provides inlay hints for positional only, variadic and keyword_variadic, which i don't think we want

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed that now

}
Type::ClassLiteral(class_literal) => ClassType::NonGeneric(class_literal)
.into_callable(db)
.into_callable(db),
Copy link
Member

Choose a reason for hiding this comment

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

Huh, why do we need to call into_callable twice. This looks fairly odd

Copy link
Contributor Author

Choose a reason for hiding this comment

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

ClassLiteral.into_callable can return bound methods, I agree it looks weird, maybe I should change the class literal function instead to convert them

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I have added more into_callable calls in ClassLiteral.into_callable

@MatthewMckee4
Copy link
Contributor Author

This doesn't seem to work well with overloads. Seems to be because of one of the internal functions from bindings maybe

@MichaReiser MichaReiser marked this pull request as draft July 14, 2025 07:51
@MatthewMckee4
Copy link
Contributor Author

@MichaReiser what are you're thoughts on this PR, what more would you like to see?

Also, is this something we really want?

@dhruvmanila
Copy link
Member

We can now also gate this behind an option similar to what @dhruvmanila did in #19780

For reference, this is what Python extension provides:

  // Enable/disable inlay hints for call argument names:
  // ```python
  // datetime('year='2019, 'month='10, 'day='27)
  // ```
  // 
  //  - off: Disable inlay hints for call argument names.
  //  - partial: Enable inlay hints for positional-or-keyword arguments while ignoring positional-only and keyword-only.
  //  - all: Enable inlay hints for positional-or-keyword and positional-only arguments while ignoring keyword-only.
  "python.analysis.inlayHints.callArgumentNames": "off",

For now, we can just start with a boolean true / false but the "partial" does seem interesting although not sure about usage metrics.

@MatthewMckee4
Copy link
Contributor Author

Cool, thanks. To be honest I didn't know the python extension provided this

@MatthewMckee4
Copy link
Contributor Author

Should we start with Boolean for all inlay hints or for both call arguments and assignments

@MichaReiser
Copy link
Member

Should we start with Boolean for all inlay hints or for both call arguments and assignments

I suggest following pylance's approach with a separate boolean option for each (we can change it to a non boolean option in the future)

Have you looked into what other Python language servers (e.g. pylance) do here?

Were you able to find out how pylance handle call argument names (e.g. how they're formatted?)

@MatthewMckee4
Copy link
Contributor Author

MatthewMckee4 commented Aug 8, 2025

They do it like it is done in this PR.

They also have some guard that prevents argument names prefixed with "_" being displayed, that seems beneficial to add here

@MichaReiser
Copy link
Member

Just checking in (no pressure). Is this waiting on any input from my end?

@MatthewMckee4
Copy link
Contributor Author

Sorry, no not really, I just haven't got to doing what I said was beneficial.

I'll get that done, then I think I'm happy with this.

@MichaReiser
Copy link
Member

Okay, no worries. I just wanted to make sure it isn't blocked on me.

@MatthewMckee4
Copy link
Contributor Author

Okay, that's all the changes I think i need to make

@MichaReiser MichaReiser enabled auto-merge (squash) August 12, 2025 13:55
@MichaReiser MichaReiser merged commit ad28b80 into astral-sh:main Aug 12, 2025
37 checks passed
@MatthewMckee4 MatthewMckee4 deleted the function-argument-inlay-hints branch August 12, 2025 13:57
@MichaReiser
Copy link
Member

Again, this is great. Thank you. I'm not yet sure how many inlay hints we want to enable in the playground but that's something we can easily tune

dcreager added a commit that referenced this pull request Aug 12, 2025
* main:
  Don't cache files with diagnostics (#19869)
  [ty] support recursive type aliases (#19805)
  [ty] Remove unsafe `salsa::Update` implementations in `tuple.rs` (#19880)
  [ty] Function argument inlay hints (#19269)
  [ty] Remove Salsa interning for `TypedDictType` (#19879)
  Fix `lint.future-annotations` link (#19876)
  [ty] Reduce memory usage of `TupleSpec` and `TupleType` (#19872)
  [ty] Track heap usage of salsa structs (#19790)
  Update salsa to pull in tracked struct changes (#19843)
  [ty] simplify CycleDetector::visit signature (#19873)
  [ty] use interior mutability in type visitors (#19871)
  [ty] Fix tool name is None when no ty path is given in ty_benchmark (#19870)
  [ty] Remove `Type::Tuple` (#19669)
  [ty] Short circuit `ReachabilityConstraints::analyze_single` for dynamic types (#19867)
dcreager added a commit that referenced this pull request Aug 13, 2025
…aints

* dcreager/inferrable: (65 commits)
  this was right after all
  mark typevars inferrable as we go
  fix tests
  fix inference of constrained typevars
  [ty] Add precise inference for indexing, slicing and unpacking `NamedTuple` instances (#19560)
  Add rule code to GitLab description (#19896)
  [ty] render docstrings in hover (#19882)
  [ty] simplify return type of place_from_declarations (#19884)
  [ty] Various minor cleanups to tuple internals (#19891)
  [ty] Improve `sys.version_info` special casing (#19894)
  Don't cache files with diagnostics (#19869)
  [ty] support recursive type aliases (#19805)
  [ty] Remove unsafe `salsa::Update` implementations in `tuple.rs` (#19880)
  [ty] Function argument inlay hints (#19269)
  [ty] Remove Salsa interning for `TypedDictType` (#19879)
  Fix `lint.future-annotations` link (#19876)
  [ty] Reduce memory usage of `TupleSpec` and `TupleType` (#19872)
  [ty] Track heap usage of salsa structs (#19790)
  Update salsa to pull in tracked struct changes (#19843)
  [ty] simplify CycleDetector::visit signature (#19873)
  ...
@dhruvmanila dhruvmanila changed the title [ty] Function argument inlay hints [ty] Add inlay hints for call arguments Aug 14, 2025
dhruvmanila added a commit to astral-sh/ty-vscode that referenced this pull request Aug 14, 2025
## Summary

Related to astral-sh/ruff#19269, this PR defines
the `ty.inlayHints.callArgumentNames` setting in the VS Code extension.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

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.

4 participants