Thanks to visit codestin.com
Credit goes to github.com

Skip to content

[ty] Render Markdown for reStructuredText fields in docstrings on hover#25903

Merged
lerebear merged 3 commits into
mainfrom
lerebear/push-ypywzttpymvv
Jun 19, 2026
Merged

[ty] Render Markdown for reStructuredText fields in docstrings on hover#25903
lerebear merged 3 commits into
mainfrom
lerebear/push-ypywzttpymvv

Conversation

@lerebear

@lerebear lerebear commented Jun 12, 2026

Copy link
Copy Markdown
Contributor

Summary

This introduces Markdown rendering for reStructuredText (reST) field lists in docstrings. Here's what it looks like in two different editors:

Before After
VS Code CleanShot 2026-06-17 at 00 02 54@2x CleanShot 2026-06-17 at 23 44 19@2x
Zed CleanShot 2026-06-17 at 00 02 19@2x CleanShot 2026-06-17 at 23 45 47@2x

The implementation includes the following judgement calls that I think are acceptable, but that we may want to revisit based on user feedback:

  • Our policy for handling malformed, unsupported, or ambiguous fields is to leave a section raw (i.e. source content, not Markdown) if even a single field in a field list cannot be confidently rendered (though other well-formed sections in the same docstring are still rendered as Markdown). I hope this policy is easy to explain, to identify and correct in practice, and to maintain.
  • We only render Markdown headings for a fixed subset of reST fields that are commonly used in docstrings. That list can be expanded in the future.
  • Types are rendered with inline code spans, and so do not receive syntax highlighting. This makes the resulting rendered docstring more compact vertically at the cost of additional visual cues.
  • Physical line breaks in field descriptions are preserved as Markdown hard breaks rather than being reflowed. This leads to some awkward line breaks in the rendered docstring, but it saves a lot of complexity in trying to identify which line breaks are actually collapsible.

I expect that it will be marginally easier to review this diff commit-by-commit rather than wholesale.

Closes astral-sh/ty#3454.

Test Plan

Please see included tests.

@astral-sh-bot astral-sh-bot Bot added server Related to the LSP server ty Multi-file analysis & type inference labels Jun 12, 2026
@codspeed-hq

codspeed-hq Bot commented Jun 12, 2026

Copy link
Copy Markdown

Merging this PR will not alter performance

✅ 71 untouched benchmarks
⏩ 64 skipped benchmarks1


Comparing lerebear/push-ypywzttpymvv (2c1519c) with main (6a41e5c)

Open in CodSpeed

Footnotes

  1. 64 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

@lerebear lerebear force-pushed the lerebear/push-ypywzttpymvv branch 2 times, most recently from 60736c0 to bb07029 Compare June 12, 2026 04:09
@lerebear lerebear force-pushed the lerebear/push-nupplxxoruqz branch 4 times, most recently from e28356b to 1e77ca4 Compare June 12, 2026 05:06
@lerebear lerebear force-pushed the lerebear/push-ypywzttpymvv branch from bb07029 to 1044385 Compare June 12, 2026 05:11
@lerebear lerebear force-pushed the lerebear/push-nupplxxoruqz branch from 1e77ca4 to 858f130 Compare June 12, 2026 05:11
Base automatically changed from lerebear/push-nupplxxoruqz to main June 12, 2026 05:30
@lerebear lerebear force-pushed the lerebear/push-ypywzttpymvv branch 6 times, most recently from 33fb99e to 7b06b44 Compare June 12, 2026 20:52
@lerebear lerebear changed the title [ty] Render Markdown for reStructuredText fields in docstrings on hover. [ty] Render Markdown for reStructuredText fields in docstrings on hover Jun 12, 2026
@lerebear lerebear force-pushed the lerebear/push-ypywzttpymvv branch from 7b06b44 to a5915aa Compare June 12, 2026 22:26
@lerebear lerebear changed the base branch from main to lerebear/push-xkyqmyxsnypl June 12, 2026 22:29
@lerebear lerebear changed the base branch from lerebear/push-xkyqmyxsnypl to lerebear/push-snllztlzlvkt June 12, 2026 22:31
@lerebear lerebear force-pushed the lerebear/push-ypywzttpymvv branch from a5915aa to 22d9d82 Compare June 12, 2026 22:32
@lerebear lerebear force-pushed the lerebear/push-snllztlzlvkt branch from ec47f0a to 7a3bc00 Compare June 13, 2026 03:24
@lerebear lerebear force-pushed the lerebear/push-ypywzttpymvv branch 6 times, most recently from 696dcc3 to 130e848 Compare June 13, 2026 20:32
@lerebear lerebear changed the base branch from lerebear/push-snllztlzlvkt to lerebear/push-ktttxvomvpou June 15, 2026 20:41
@lerebear lerebear force-pushed the lerebear/push-ypywzttpymvv branch 3 times, most recently from 9591e65 to 350dbe0 Compare June 15, 2026 22:07
@lerebear lerebear force-pushed the lerebear/push-ktttxvomvpou branch from 3da034f to 2a18e16 Compare June 15, 2026 22:15
@lerebear lerebear changed the base branch from lerebear/push-ktttxvomvpou to lerebear/push-snllztlzlvkt June 15, 2026 22:25
@lerebear lerebear force-pushed the lerebear/push-ypywzttpymvv branch from 350dbe0 to e8f24f4 Compare June 15, 2026 22:25
@lerebear lerebear force-pushed the lerebear/push-snllztlzlvkt branch from 1e31619 to 757bb8b Compare June 15, 2026 22:45
@lerebear lerebear force-pushed the lerebear/push-ypywzttpymvv branch from e8f24f4 to 80e5e76 Compare June 15, 2026 22:45
@lerebear lerebear force-pushed the lerebear/push-snllztlzlvkt branch from 757bb8b to 8f6f03f Compare June 16, 2026 00:17
@lerebear lerebear force-pushed the lerebear/push-ypywzttpymvv branch 2 times, most recently from b83e328 to 05760d0 Compare June 16, 2026 03:35
@lerebear lerebear force-pushed the lerebear/push-snllztlzlvkt branch 2 times, most recently from 741163a to 894a1eb Compare June 16, 2026 03:52
@lerebear lerebear force-pushed the lerebear/push-ypywzttpymvv branch 2 times, most recently from edcdbfc to 89301b9 Compare June 16, 2026 04:45
@lerebear lerebear force-pushed the lerebear/push-snllztlzlvkt branch 2 times, most recently from 6ed67b7 to f8a5bf4 Compare June 16, 2026 05:20
@lerebear lerebear force-pushed the lerebear/push-ypywzttpymvv branch from 89301b9 to d94888e Compare June 16, 2026 05:20
@lerebear lerebear force-pushed the lerebear/push-snllztlzlvkt branch from f8a5bf4 to 00c292a Compare June 16, 2026 21:19
@lerebear lerebear force-pushed the lerebear/push-ypywzttpymvv branch from d94888e to b6afe06 Compare June 16, 2026 21:19
@lerebear lerebear force-pushed the lerebear/push-snllztlzlvkt branch from 00c292a to a6102eb Compare June 16, 2026 21:46

@MichaReiser MichaReiser left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thank you, this is great!

Here are two codex finding. You'll know better whether these need to be addressed or not.

[P3] Keep Sphinx parameter aliases in the same section.
key and keyword are parsed separately and rendered under “Keyword Arguments.” Sphinx defines them as aliases of param/argument, not as evidence that a parameter is keyword-only. This can misleadingly split one parameter list into two headings. They should remain Parameters unless semantic signature information drives the distinction. Sphinx reference

[P3] Parse field names case-insensitively.
The literal match in parse_supported rejects valid capitalization such as :Param value: or :Returns:. If mixed with lowercase fields, the unknown-field fallback keeps the entire list raw. reST field names are case-insensitive when transformed, so dispatch should normalize or compare ASCII-insensitively. reStructuredText specification

Comment thread crates/ty_ide/src/docstring/document/rst.rs
Comment thread crates/ty_ide/src/docstring/document/rst.rs Outdated
Comment thread crates/ty_ide/src/docstring/document/rst.rs Outdated
Comment thread crates/ty_ide/src/docstring/markdown/structured/rst.rs Outdated
Comment thread crates/ty_ide/src/docstring/markdown/structured/rst.rs Outdated
Comment thread crates/ty_ide/src/docstring/markdown/structured/rst.rs Outdated
Comment thread crates/ty_ide/src/docstring/markdown/structured/rst.rs Outdated
Comment thread crates/ty_ide/src/docstring/markdown.rs Outdated
@AlexWaygood

Copy link
Copy Markdown
Member

I haven't reviewed the code, but the output in the PR summary looks awesome! Just one nit on that front:

image

To me it would look better here if we had a line break after "Source str | pathlib.Path" here? And then "Location to read" started its own line?

That's the style I'm most familiar with in Python documentation elsewhere -- e.g. numpy, pandas. Or other documentation themes often use a table, but still generally keep the description of the parameter more clearly separated from its name and type annotation -- e.g. textual, my own typeshed-stats project

@lerebear

Copy link
Copy Markdown
Contributor Author

Here are two codex finding. You'll know better whether these need to be addressed or not.

Thank you for sharing: I addressed both. The first in particular was interesting, and made be reconsider previous behaviour (we now isolate the "Keyword Arguments" section to Google-formatted docstrings, which is where they belong).

To me it would look better here if we had a line break after "Source str | pathlib.Path" here? And then "Location to read" started its own line?

Yes, thank you for the feedback! I've implemented just that (pictured below).

I would have loved to also indent the parameter docs (as in the numpy and pandas examples you shared, and also as Pylance does), but I couldn't figure out how to do so without an editor-specific hack1. I think the result is imperfect, but probably better than what I had before. We should adjust this as necessary in response to user feedback.

pre-ul-ty-2-vscode-light

Footnotes

  1. The hack was to put each parameter in a bare <ul> (without an <li>, so as not to get the default bullet prefix) to force an indentation context without modifying the source (and thus potentially breaking markdown syntax in the source text)2. That is not semantically-valid HTML, so it is not guaranteed to be rendered correctly, although VS Code specifically appears to do so. For reference, prototypes for that approach were implemented across this ruff patch and this ty-vscode patch.

  2. Additionally, this also required reliance on the general.markdown.allowedTags capability from the client.

lerebear added 3 commits June 19, 2026 00:03
Associate Markdown rendering with docstring fragments

Test reST parameter extraction boundaries

Share reST field-list boundary filtering
@marcofrasvda

Copy link
Copy Markdown

This was one of the main things I missed coming from Pyright/Pylance, can't wait to try it, thanks!

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.

Render markdown for reStructuredText field lists in docstrings

4 participants