Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CONFIGURATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ This server can be configured using the `workspace/didChangeConfiguration` metho
| `pylsp.rope.extensionModules` | `string` | Builtin and c-extension modules that are allowed to be imported and inspected by rope. | `null` |
| `pylsp.rope.ropeFolder` | `array` of unique `string` items | The name of the folder in which rope stores project configurations and data. Pass `null` for not using such a folder at all. | `null` |
| `pylsp.signature.formatter` | `string` (one of: `'black'`, `'ruff'`, `None`) | Formatter to use for reformatting signatures in docstrings. | `"black"` |
| `pylsp.signature.include_docstring` | `boolean` | Include signature docstring. | `true` |
| `pylsp.signature.line_length` | `number` | Maximum line length in signatures. | `88` |

This documentation was generated from `pylsp/config/schema.json`. Please do not edit this file directly.
29 changes: 18 additions & 11 deletions pylsp/_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -315,17 +315,24 @@ def format_docstring(
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:
wrapped_signatures = convert_signatures_to_markdown(
signatures, config=signature_config or {}
)
value = wrapped_signatures + "\n\n" + value
wrapped_signatures = convert_signatures_to_markdown(
signatures if signatures is not None else [], config=signature_config or {}
)

if contents != "":
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 = wrapped_signatures + "\n\n" + value
else:
value = contents

if signatures:
value = wrapped_signatures

return {"kind": "markdown", "value": value}
value = contents
Expand Down
5 changes: 5 additions & 0 deletions pylsp/config/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -530,6 +530,11 @@
"default": "black",
"description": "Formatter to use for reformatting signatures in docstrings."
},
"pylsp.signature.include_docstring": {
"type": "boolean",
"default": true,
"description": "Include signature docstring."
},
"pylsp.signature.line_length": {
"type": "number",
"default": 88,
Expand Down
13 changes: 11 additions & 2 deletions pylsp/plugins/hover.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,19 @@ def pylsp_hover(config, document, position):
"",
)

include_docstring = signature_config.get("include_docstring", True)

# raw docstring returns only doc, without signature
docstring = definition.docstring(raw=True)
if include_docstring is False:
if signature:
docstring = ""
else:
docstring = docstring.strip().split("\n")[0].strip()

return {
"contents": _utils.format_docstring(
# raw docstring returns only doc, without signature
definition.docstring(raw=True),
docstring,
preferred_markup_kind,
signatures=[signature] if signature else None,
signature_config=signature_config,
Expand Down
8 changes: 7 additions & 1 deletion pylsp/plugins/signature.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

@hookimpl
def pylsp_signature_help(config, document, position):
signature_config = config.settings().get("signature", {})
code_position = _utils.position_to_jedi_linecolumn(document, position)
signatures = document.jedi_script().get_signatures(**code_position)

Expand All @@ -41,10 +42,15 @@ def pylsp_signature_help(config, document, position):
# Docstring contains one or more lines of signature, followed by empty line, followed by docstring
function_sig_lines = (docstring.split("\n\n") or [""])[0].splitlines()
function_sig = " ".join([line.strip() for line in function_sig_lines])

signature_docstring = s.docstring(raw=True)
if signature_config.get("include_docstring", True) is False:
signature_docstring = ""

sig = {
"label": function_sig,
"documentation": _utils.format_docstring(
s.docstring(raw=True), markup_kind=preferred_markup_kind
signature_docstring, markup_kind=preferred_markup_kind
),
}

Expand Down
14 changes: 14 additions & 0 deletions test/fixtures.py
Original file line number Diff line number Diff line change
Expand Up @@ -177,3 +177,17 @@ def client_server_pair() -> None:
).result(timeout=CALL_TIMEOUT_IN_SECONDS)
assert shutdown_response is None
client_server_pair_obj.client._endpoint.notify("exit")


@pytest.fixture
def workspace_with_signature_docstring_disabled(workspace) -> None:
workspace._config.update(
{
"signature": {
**workspace._config.settings().get("signature", {}),
"include_docstring": False,
},
}
)

yield workspace
14 changes: 14 additions & 0 deletions test/plugins/test_hover.py
Original file line number Diff line number Diff line change
Expand Up @@ -143,3 +143,17 @@ def foo():
contents = pylsp_hover(doc._config, doc, cursor_pos)["contents"]

assert "A docstring for foo." in contents["value"]


def test_hover_without_docstring(workspace_with_signature_docstring_disabled) -> None:
# Over 'main' in def main():
hov_position = {"line": 2, "character": 6}

doc = Document(DOC_URI, workspace_with_signature_docstring_disabled, DOC)

contents = {
"kind": "markdown",
"value": "```python\nmain(a: float, b: float)\n```\n",
}

assert {"contents": contents} == pylsp_hover(doc._config, doc, hov_position)
14 changes: 14 additions & 0 deletions test/plugins/test_signature.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,3 +104,17 @@ def test_docstring_params(regex, doc) -> None:
m = regex.match(doc)
assert m.group("param") == "test"
assert m.group("doc") == "parameter docstring"


def test_signature_without_docstring(
workspace_with_signature_docstring_disabled,
) -> None:
# Over '( ' in main(
sig_position = {"line": 10, "character": 5}
doc = Document(DOC_URI, workspace_with_signature_docstring_disabled, DOC)

sig_info = signature.pylsp_signature_help(doc._config, doc, sig_position)

sigs = sig_info["signatures"]
assert len(sigs) == 1
assert sigs[0]["documentation"] == {"kind": "markdown", "value": ""}