8000 Remove pluggy racing (#222) · python-lsp/python-lsp-server@af4dcb3 · GitHub
[go: up one dir, main page]

Skip to content

Commit af4dcb3

Browse files
authored
Remove pluggy racing (#222)
* Completion: Remove pluggy racing and disable Rope by default This allows the user to choose between Rope and Jedi for completions. It also remove the pluggy racing since Jedi's cache isn't thread safe. Closes #189 * Only use single completion hook * Remove pluggy and disable rope completions by default * Remove pluggy
1 parent 166967b commit af4dcb3

File tree

5 files changed

+45
-79
lines changed

5 files changed

+45
-79
lines changed

pyls/_utils.py

Lines changed: 0 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -89,33 +89,6 @@ def _merge_dicts_(a, b):
8989
return dict(_merge_dicts_(dict_a, dict_b))
9090

9191

92-
def race_hooks(hook_caller, pool, **kwargs):
93-
"""Given a pluggy hook spec, execute impls in parallel returning the first non-None result.
94-
95-
Note this does not support a lot of pluggy functionality, e.g. hook wrappers.
96-
"""
97-
impls = hook_caller._nonwrappers + hook_caller._wrappers
98-
log.debug("Racing hook impls for hook %s: %s", hook_caller, impls)
99-
100-
if not impls:
101-
return None
102-
103-
def _apply(impl):
104-
try:
105-
return impl, impl.function(**kwargs)
106-
except Exception:
107-
log.exception("Failed to run hook %s", impl.plugin_name)
108-
raise
109-
110-
# imap unordered gives us an iterator over the items in the order they finish.
111-
# We have to be careful to set chunksize to 1 to ensure hooks each get their own thread.
112-
# Unfortunately, there's no way to interrupt these threads, so we just have to leave them be.
113-
for impl, result in pool.imap_unordered(_apply, impls, chunksize=1):
114-
if result is not None:
115-
log.debug("Hook from plugin %s returned: %s", impl.plugin_name, result)
116-
return result
117-
118-
11992
def format_docstring(contents):
12093
"""Python doc strings come in a number of formats, but LSP wants markdown.
12194

pyls/plugins/jedi_completion.py

Lines changed: 33 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,21 @@
11
# Copyright 2017 Palantir Technologies, Inc.
22
import logging
3-
from pyls.lsp import CompletionItemKind
4-
from pyls import hookimpl, _utils
3+
from pyls import hookimpl, lsp, _utils
54

65
log = logging.getLogger(__name__)
76

87

98
@hookimpl
109
def pyls_completions(document, position):
11-
log.debug('Launching Jedi')
1210
definitions = document.jedi_script(position).completions()
13-
definitions = [{
11+
return [{
1412
'label': _label(d),
1513
'kind': _kind(d),
1614
'detail': _detail(d),
1715
'documentation': _utils.format_docstring(d.docstring()),
1816
'sortText': _sort_text(d),
1917
'insertText': d.name
20-
} for d in definitions]
21-
log.debug('Jedi finished')
22-
return definitions
18+
} for d in definitions] or None
2319

2420

2521
def _label(definition):
@@ -53,36 +49,36 @@ def _sort_text(definition):
5349
def _kind(d):
5450
""" Return the VSCode type """
5551
MAP = {
56-
'none': CompletionItemKind.Value,
57-
'type': CompletionItemKind.Class,
58-
'tuple': CompletionItemKind.Class,
59-
'dict': CompletionItemKind.Class,
60-
'dictionary': CompletionItemKind.Class,
61-
'function': CompletionItemKind.Function,
62-
'lambda': CompletionItemKind.Function,
63-
'generator': CompletionItemKind.Function,
64-
'class': CompletionItemKind.Class,
65-
'instance': CompletionItemKind.Reference,
66-
'method': CompletionItemKind.Method,
67-
'builtin': CompletionItemKind.Class,
68-
'builtinfunction': CompletionItemKind.Function,
69-
'module': CompletionItemKind.Module,
70-
'file': CompletionItemKind.File,
71-
'xrange': CompletionItemKind.Class,
72-
'slice': CompletionItemKind.Class,
73-
'traceback': CompletionItemKind.Class,
74-
'frame': CompletionItemKind.Class,
75-
'buffer': CompletionItemKind.Class,
76-
'dictproxy': CompletionItemKind.Class,
77-
'funcdef': CompletionItemKind.Function,
78-
'property': CompletionItemKind.Property,
79-
'import': CompletionItemKind.Module,
80-
'keyword': CompletionItemKind.Keyword,
81-
'constant': CompletionItemKind.Variable,
82-
'variable': CompletionItemKind.Variable,
83-
'value': CompletionItemKind.Value,
84-
'param': CompletionItemKind.Variable,
85-
'statement': CompletionItemKind.Keyword,
52+
'none': lsp.CompletionItemKind.Value,
53+
'type': lsp.CompletionItemKind.Class,
54+
'tuple': lsp.CompletionItemKind.Class,
55+
'dict': lsp.CompletionItemKind.Class,
56+
'dictionary': lsp.CompletionItemKind.Class,
57+
'function': lsp.CompletionItemKind.Function,
58+
'lambda': lsp.CompletionItemKind.Function,
59+
'generator': lsp.CompletionItemKind.Function,
60+
'class': lsp.CompletionItemKind.Class,
61+
'instance': lsp.CompletionItemKind.Reference,
62+
'method': lsp.CompletionItemKind.Method,
63+
'builtin': lsp.CompletionItemKind.Class,
64+
'builtinfunction': lsp.CompletionItemKind.Function,
65+
'module': lsp.CompletionItemKind.Module,
66+
'file': lsp.CompletionItemKind.File,
67+
'xrange': lsp.CompletionItemKind.Class,
68+
'slice': lsp.CompletionItemKind.Class,
69+
'traceback': lsp.CompletionItemKind.Class,
70+
'frame': lsp.CompletionItemKind.Class,
71+
'buffer': lsp.CompletionItemKind.Class,
72+
'dictproxy': lsp.CompletionItemKind.Class,
73+
'funcdef': lsp.CompletionItemKind.Function,
74+
'property': lsp.CompletionItemKind.Property,
75+
'import': lsp.CompletionItemKind.Module,
76+
'keyword': lsp.CompletionItemKind.Keyword,
77+
'constant': lsp.CompletionItemKind.Variable,
78+
'variable': lsp.CompletionItemKind.Variable,
79+
'value': lsp.CompletionItemKind.Value,
80+
'param': lsp.CompletionItemKind.Variable,
81+
'statement': lsp.CompletionItemKind.Keyword,
8682
}
8783

8884
return MAP.get(d.type)

pyls/plugins/rope_completion.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,13 @@
99

1010

1111
@hookimpl
12-
def pyls_completions(document, position):
13-
log.debug('Launching Rope')
12+
def pyls_settings():
13+
# Default rope_completion to disabled
14+
return {'plugins': {'rope_completion': {'enabled': False}}}
15+
1416

17+
@hookimpl
18+
def pyls_completions(document, position):
1519
# Rope is a bit rubbish at completing module imports, so we'll return None
1620
word = document.word_at_position({
1721
# The -1 should really be trying to look at the previous word, but that might be quite expensive
@@ -40,7 +44,7 @@ def pyls_completions(document, position):
4044
'documentation': doc or "",
4145
'sortText': _sort_text(d)})
4246
definitions = new_definitions
43-
log.debug('Rope finished')
47+
4448
return definitions or None
4549

4650

pyls/python_ls.py

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,12 @@
11
# Copyright 2017 Palantir Technologies, Inc.
22
import logging
3-
from multiprocessing import dummy as multiprocessing
43
from . import lsp, _utils
54
from .config import config
65
from .language_server import LanguageServer
76
from .workspace import Workspace
87

98
log = logging.getLogger(__name__)
109

11-
PLUGGY_RACE_POOL_SIZE = 5
1210
LINT_DEBOUNCE_S = 0.5 # 500 ms
1311

1412

@@ -21,8 +19,6 @@ class PythonLanguageServer(LanguageServer):
2119
# Set of method dispatchers to query
2220
_dispatchers = []
2321

24-
_pool = multiprocessing.Pool(PLUGGY_RACE_POOL_SIZE)
25-
2622
def __getitem__(self, item):
2723
"""Override the method dispatcher to farm out any unknown messages to our plugins."""
2824
try:
@@ -41,7 +37,8 @@ def _hook_caller(self, hook_name):
4137

4238
def _hook(self, hook_name, doc_uri=None, **kwargs):
4339
doc = self.workspace.get_document(doc_uri) if doc_uri else None
44-
return self._hook_caller(hook_name)(config=self.config, workspace=self.workspace, document=doc, **kwargs)
40+
hook = self.config.plugin_manager.subset_hook_caller(hook_name, self.config.disabled_plugins)
41+
return hook(config=self.config, workspace=self.workspace, document=doc, **kwargs)
4542

4643
def capabilities(self):
4744
server_capabilities = {
@@ -85,14 +82,10 @@ def code_lens(self, doc_uri):
8582
return flatten(self._hook('pyls_code_lens', doc_uri))
8683

8784
def completions(self, doc_uri, position):
88-
completions = _utils.race_hooks(
89-
self._hook_caller('pyls_completions'), self._pool,
90-
document=self.workspace< 9E7A /span>.get_document(doc_uri) if doc_uri else None,
91-
position=position
92-
)
85+
completions = self._hook('pyls_completions', doc_uri, position=position)
9386
return {
9487
'isIncomplete': False,
95-
'items': completions or []
88+
'items': flatten(completions)
9689
}
9790

9891
def definitions(self, doc_uri, position):

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,6 @@
6161
'pyls = pyls.__main__:main',
6262
],
6363
'pyls': [
64-
'rope_completion = pyls.plugins.rope_completion',
6564
'jedi_completion = pyls.plugins.jedi_completion',
6665
'jedi_definition = pyls.plugins.definition',
6766
'jedi_hover = pyls.plugins.hover',
@@ -72,6 +71,7 @@
7271
'pycodestyle = pyls.plugins.pycodestyle_lint',
7372
'pydocstyle = pyls.plugins.pydocstyle_lint',
7473
'pyflakes = pyls.plugins.pyflakes_lint',
74+
'rope_completion = pyls.plugins.rope_completion',
7575
'rope_rename = pyls.plugins.rope_rename',
7676
'yapf = pyls.plugins.format',
7777
]

0 commit comments

Comments
 (0)
0