8000 Formatting of signatures in docstrings · Issue #630 · python-lsp/python-lsp-server · GitHub
[go: up one dir, main page]

Skip to content

Formatting of signatures in docstrings #630

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
krassowski opened this issue Mar 31, 2025 · 0 comments
Open

Formatting of signatures in docstrings #630

krassowski opened this issue Mar 31, 2025 · 0 comments
Labels
enhancement New feature or request

Comments

@krassowski
Copy link
Member

Problem

The formatting of signatures in hover and code completion documentation is fine for signatures of small functions:

Image

but is not necessarily readable for functions with many complex arguments:

Image

Proposed solution

Add a hook allowing to format the signature with a formatter of choice, e.g. with black. Users could then customize the number of characters in a lines, wrapping, and potentially custom highlighting (instead of using code fences).

Context

Currently docstrings in hover and completion documentation are composed of two parts:

  • signature
  • the docstring itself

The docstring gets formatted by docstring-to-markdown which now supports entrypoints allowing to add support for custom formats used in internal codebases or to override the formatting.

def format_docstring(
contents: str, markup_kind: str, signatures: Optional[List[str]] = None
):
"""Transform the provided docstring into a MarkupContent object.
If `markup_kind` is 'markdown' the docstring will get converted to
markdown representation using `docstring-to-markdown`; if it is
`plaintext`, it will be returned as plain text.
Call signatures of functions (or equivalent code summaries)
provided in optional `signatures` argument will be prepended
to the provided contents of the docstring if given.
"""
if not isinstance(contents, str):
contents = ""
if markup_kind == "markdown":
try:
value = docstring_to_markdown.convert(contents)
except docstring_to_markdown.UnknownFormatError:
# try to escape the Markdown syntax instead:
value = escape_markdown(contents)
if signatures:
value = wrap_signature("\n".join(signatures)) + "\n\n" + value
return {"kind": "markdown", "value": value}
value = contents
if signatures:
value = "\n".join(signatures) + "\n\n" + value
return {"kind": "plaintext", "value": escape_plain_text(value)}

The signature part formatting is hard-coded to use wrap_signature:

def wrap_signature(signature):
return "```python\n" + signature + "\n```\n"

The signature strings come from jedi's BaseSignature.to_string() method:

docs = _utils.format_docstring(
d.docstring(raw=True),
signatures=[signature.to_string() for signature in d.get_signatures()],
markup_kind=markup_kind,

# Find first exact matching signature
signature = next(
(
x.to_string()
for x in definition.get_signatures()
if (x.name == word and x.type not in ["module"])
),
"",
)
return {
"contents": _utils.format_docstring(
# raw docstring returns only doc, without signature
definition.docstring(raw=True),
preferred_markup_kind,
signatures=[signature] if signature else None,
)
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

1 participant
0