Skip to content

Commit

Permalink
Fix Jedi type map (use types offered by modern Jedi)
Browse files Browse the repository at this point in the history
  • Loading branch information
krassowski committed Apr 25, 2021
1 parent 977ca39 commit 5002197
Show file tree
Hide file tree
Showing 2 changed files with 88 additions and 29 deletions.
40 changes: 11 additions & 29 deletions pylsp/plugins/jedi_completion.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,39 +10,21 @@

log = logging.getLogger(__name__)

# Map to the VSCode type
# Map to the LSP type
# > Valid values for type are ``module``, `` class ``, ``instance``, ``function``,
# > ``param``, ``path``, ``keyword``, ``property`` and ``statement``.
# see: https://jedi.readthedocs.io/en/latest/docs/api-classes.html#jedi.api.classes.BaseName.type
_TYPE_MAP = {
'none': lsp.CompletionItemKind.Value,
'type': lsp.CompletionItemKind.Class,
'tuple': lsp.CompletionItemKind.Class,
'dict': lsp.CompletionItemKind.Class,
'dictionary': lsp.CompletionItemKind.Class,
'function': lsp.CompletionItemKind.Function,
'lambda': lsp.CompletionItemKind.Function,
'generator': lsp.CompletionItemKind.Function,
'module': lsp.CompletionItemKind.Module,
'namespace': lsp.CompletionItemKind.Module, # to be added in Jedi 0.18+
'class': lsp.CompletionItemKind.Class,
'instance': lsp.CompletionItemKind.Reference,
'method': lsp.CompletionItemKind.Method,
'builtin': lsp.CompletionItemKind.Class,
'builtinfunction': lsp.CompletionItemKind.Function,
'module': lsp.CompletionItemKind.Module,
'file': lsp.CompletionItemKind.File,
'path': lsp.CompletionItemKind.Text,
'xrange': lsp.CompletionItemKind.Class,
'slice': lsp.CompletionItemKind.Class,
'traceback': lsp.CompletionItemKind.Class,
'frame': lsp.CompletionItemKind.Class,
'buffer': lsp.CompletionItemKind.Class,
'dictproxy': lsp.CompletionItemKind.Class,
'funcdef': lsp.CompletionItemKind.Function,
'property': lsp.CompletionItemKind.Property,
'import': lsp.CompletionItemKind.Module,
'keyword': lsp.CompletionItemKind.Keyword,
'constant': lsp.CompletionItemKind.Variable,
'variable': lsp.CompletionItemKind.Variable,
'value': lsp.CompletionItemKind.Value,
'function': lsp.CompletionItemKind.Function,
'param': lsp.CompletionItemKind.Variable,
'statement': lsp.CompletionItemKind.Keyword,
'path': lsp.CompletionItemKind.File,
'keyword': lsp.CompletionItemKind.Keyword,
'property': lsp.CompletionItemKind.Property, # added in Jedi 0.18
'statement': lsp.CompletionItemKind.Variable
}

# Types of parso nodes for which snippet is not included in the completion
Expand Down
77 changes: 77 additions & 0 deletions test/plugins/test_completion.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
import os
import sys

from pathlib import Path
from typing import NamedTuple, Dict

import pytest

from pylsp import uris, lsp
Expand Down Expand Up @@ -50,6 +53,80 @@ def test_rope_import_completion(config, workspace):
assert items is None


class TypeCase(NamedTuple):
document: str
position: dict
label: str
expected: lsp.CompletionItemKind


TYPE_CASES: Dict[str, TypeCase] = {
'variable': TypeCase(
document='test = 1\ntes',
position={'line': 1, 'character': 3},
label='test',
expected=lsp.CompletionItemKind.Variable
),
'function': TypeCase(
document='def test():\n pass\ntes',
position={'line': 2, 'character': 3},
label='test()',
expected=lsp.CompletionItemKind.Function
),
'keyword': TypeCase(
document='fro',
position={'line': 0, 'character': 3},
label='from',
expected=lsp.CompletionItemKind.Keyword
),
'file': TypeCase(
document='"' + __file__[:-2].replace('"', '\\"') + '"',
position={'line': 0, 'character': len(__file__) - 2},
label=Path(__file__).name + '"',
expected=lsp.CompletionItemKind.File
),
'module': TypeCase(
document='import statis',
position={'line': 0, 'character': 13},
label='statistics',
expected=lsp.CompletionItemKind.Module
),
'class': TypeCase(
document='KeyErr',
position={'line': 0, 'character': 6},
label='KeyError',
expected=lsp.CompletionItemKind.Class
),
'property': TypeCase(
document=(
'class A:\n'
' @property\n'
' def test(self):\n'
' pass\n'
'A().tes'
),
position={'line': 4, 'character': 5},
label='test',
expected=lsp.CompletionItemKind.Property
)
}


@pytest.mark.parametrize('case', list(TYPE_CASES.values()), ids=list(TYPE_CASES.keys()))
def test_jedi_completion_type(case, config, workspace):
# pylint: disable=C0415
import jedi

# property support was introduced in 0.18
if case.expected == lsp.CompletionItemKind.Property and jedi.__version__.startswith('0.17'):
return

doc = Document(DOC_URI, workspace, case.document)
items = pylsp_jedi_completions(config, doc, case.position)
items = {i['label']: i for i in items}
assert items[case.label]['kind'] == case.expected


def test_jedi_completion(config, workspace):
# Over 'i' in os.path.isabs(...)
com_position = {'line': 1, 'character': 15}
Expand Down

0 comments on commit 5002197

Please sign in to comment.