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
5 changes: 4 additions & 1 deletion pylsp/plugins/definition.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,10 @@ def pylsp_definitions(
},
}
for d in definitions
if d.is_definition() and (follow_builtin_defns or _not_internal_definition(d))
if d.is_definition()
and d.line is not None
and d.column is not None
and (follow_builtin_defns or _not_internal_definition(d))
]


Expand Down
26 changes: 26 additions & 0 deletions test/plugins/test_definitions.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@

import os

import jedi

from pylsp import uris
from pylsp.plugins.definition import pylsp_definitions
from pylsp.workspace import Document
Expand Down Expand Up @@ -173,3 +175,27 @@ def foo():
assert [{"uri": module_uri, "range": def_range}] == pylsp_definitions(
config, doc, cursor_pos
)


def test_definition_without_source_position(config, workspace, monkeypatch) -> None:
# A definition jedi resolves without a source position (e.g. a compiled
# builtin, where line/column are None) must be dropped, not crash with
# `TypeError: unsupported operand type(s) for -: 'NoneType' and 'int'`.
# Regression test for #623 and #624.
class _NoPositionName:
line = None
column = None
module_path = None
name = "compiled"

def is_definition(self) -> bool:
return True

monkeypatch.setattr(
jedi.api.Script, "goto", lambda *args, **kwargs: [_NoPositionName()]
)

doc = Document(DOC_URI, workspace, DOC)
# follow_builtin_definitions defaults to True, so the None-guard in the
# return comprehension is the only thing preventing the crash.
assert pylsp_definitions(config, doc, {"line": 3, "character": 6}) == []