Skip to content

Commit 0457426

Browse files
authored
Respect updates to sys path without closing/opening a document (#219)
* Respect updates to sys path * Respect updates to sys path
1 parent 4ae91dc commit 0457426

File tree

3 files changed

+32
-21
lines changed

3 files changed

+32
-21
lines changed

pyls/workspace.py

Lines changed: 22 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,8 @@ def get_document(self, doc_uri):
112112
def put_document(self, doc_uri, content, version=None):
113113
path = uris.to_fs_path(doc_uri)
114114
self._docs[doc_uri] = Document(
115-
doc_uri, content, sys_path=self.syspath_for_path(path), version=version, rope=self._rope
115+
doc_uri, content,
116+
extra_sys_path=self.source_roots(path), version=version, rope=self._rope
116117
)
117118

118119
def rm_document(self, doc_uri):
@@ -136,35 +137,23 @@ def show_message(self, message, msg_type=lsp.MessageType.Info):
136137
params = {'type': msg_type, 'message': message}
137138
self._lang_server.notify(self.M_SHOW_MESSAGE, params)
138139

139-
def syspath_for_path(self, path):
140-
"""Construct a sensible sys path to use for the given file path.
141-
142-
Since the workspace root may not be the root of the Python project we instead
143-
append the closest parent directory containing a setup.py file.
144-
"""
145-
files = _utils.find_parents(self._root_path, path, ['setup.py']) or []
146-
path = [os.path.dirname(setup_py) for setup_py in files]
147-
148-
# Check to see if we're in a virtualenv
149-
if 'VIRTUAL_ENV' in os.environ:
150-
log.info("Using virtualenv %s", os.environ['VIRTUAL_ENV'])
151-
path.extend(jedi.evaluate.sys_path.get_venv_path(os.environ['VIRTUAL_ENV']))
152-
else:
153-
path.extend(sys.path)
154-
return path
140+
def source_roots(self, document_path):
141+
"""Return the source roots for the given document."""
142+
files = _utils.find_parents(self._root_path, document_path, ['setup.py']) or []
143+
return [os.path.dirname(setup_py) for setup_py in files]
155144

156145

157146
class Document(object):
158147

159-
def __init__(self, uri, source=None, version=None, local=True, sys_path=None, rope=None):
148+
def __init__(self, uri, source=None, version=None, local=True, extra_sys_path=None, rope=None):
160149
self.uri = uri
161150
self.version = version
162151
self.path = uris.to_fs_path(uri)
163152
self.filename = os.path.basename(self.path)
164153

165154
self._local = local
166155
self._source = source
167-
self._sys_path = sys_path or sys.path
156+
self._extra_sys_path = extra_sys_path or []
168157
self._rope_project = rope
169158

170159
def __str__(self):
@@ -260,9 +249,22 @@ def jedi_script(self, position=None):
260249
kwargs = {
261250
'source': self.source,
262251
'path': self.path,
263-
'sys_path': self._sys_path
252+
'sys_path': self.sys_path()
264253
}
265254
if position:
266255
kwargs['line'] = position['line'] + 1
267256
kwargs['column'] = _utils.clip_column(position['character'], self.lines, position['line'])
268257
return jedi.Script(**kwargs)
258+
259+
def sys_path(self):
260+
# Copy our extra sys path
261+
path = list(self._extra_sys_path)
262+
263+
# Check to see if we're in a virtualenv
264+
if 'VIRTUAL_ENV' in os.environ:
265+
log.info("Using virtualenv %s", os.environ['VIRTUAL_ENV'])
266+
path.extend(jedi.evaluate.sys_path.get_venv_path(os.environ['VIRTUAL_ENV']))
267+
else:
268+
path.extend(sys.path)
269+
270+
return path

test/test_document.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
# Copyright 2017 Palantir Technologies, Inc.
2+
import sys
23
import pytest
34
from pyls import uris
45
from pyls.workspace import Document
@@ -48,6 +49,14 @@ def test_word_at_position(doc):
4849
assert doc.word_at_position({'line': 4, 'character': 0}) == ''
4950

5051

52+
def test_document_sys_path(doc):
53+
"""Test the document's sys path is updated."""
54+
assert 'foo' not in doc.sys_path()
55+
sys.path.append('foo')
56+
# Check that the new sys path is included in the doc's sys path
57+
assert 'foo' in doc.sys_path()
58+
59+
5160
def test_document_empty_edit():
5261
doc = Document('file:///uri', u'')
5362
doc.apply_change({

test/test_workspace.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,4 +46,4 @@ def test_non_root_project(pyls):
4646
test_uri = uris.from_fs_path(os.path.join(project_root, 'hello/test.py'))
4747
pyls.workspace.put_document(test_uri, 'assert True')
4848
test_doc = pyls.workspace.get_document(test_uri)
49-
assert project_root in pyls.workspace.syspath_for_path(test_doc.path)
49+
assert project_root in test_doc.sys_path()

0 commit comments

Comments
 (0)