Skip to content

Commit

Permalink
Support python projects in subdirectories (#34)
Browse files Browse the repository at this point in the history
* Create test for non-root syspath

* Implement syspaths
  • Loading branch information
gatesn authored Mar 29, 2017
1 parent 77e008c commit 15e19cd
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 4 deletions.
3 changes: 1 addition & 2 deletions pyls/providers/base.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
# Copyright 2017 Palantir Technologies, Inc.
import os
import jedi
import sys


class BaseProvider(object):
Expand All @@ -23,7 +22,7 @@ def jedi_script(self, doc_uri, position=None):
document = self.workspace.get_document(doc_uri)

path = None
sys_path = list(sys.path) # TODO Load from config
sys_path = self.workspace.syspath_for_document(document)

# If we're local, we can add ourselves to Python path and do clevererer things
if self.workspace.is_local():
Expand Down
12 changes: 12 additions & 0 deletions pyls/workspace.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# Copyright 2017 Palantir Technologies, Inc.
import os
import re
import sys
from urllib.parse import urlparse, urlunparse

# TODO: this is not the best e.g. we capture numbers
Expand Down Expand Up @@ -51,6 +52,17 @@ def get_uri_like(self, doc_uri, path):
parts[2] = path
return urlunparse([str(p) for p in parts])

def syspath_for_document(self, document):
""" Construct a sensible sys path to use for the given document.
Since the workspace root may not be the root of the Python project we instead
append the closest parent directory containing a setup.py file.
"""
files = self.find_config_files(document, ['setup.py']) or []
path = [os.path.dirname(setup_py) for setup_py in files]
path.extend(sys.path)
return path

def _check_in_workspace(self, doc_uri):
doc_path = urlparse(doc_uri).path
if not os.path.commonprefix((self.root, doc_path)):
Expand Down
4 changes: 2 additions & 2 deletions test/fixtures.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,15 @@


@pytest.fixture
def pyls():
def pyls(tmpdir):
""" Return an initialized python LS """
rfile = StringIO()
wfile = StringIO()
ls = PythonLanguageServer(rfile, wfile)

ls.m_initialize(
processId=1,
rootPath=os.path.dirname(__file__),
rootPath=str(tmpdir),
initializationOptions={}
)

Expand Down
17 changes: 17 additions & 0 deletions test/test_workspace.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# Copyright 2017 Palantir Technologies, Inc.
import os
import pytest
from pyls.workspace import Workspace

DOC_URI = 'file://' + __file__

Expand Down Expand Up @@ -34,3 +36,18 @@ def test_bad_get_document(pyls):

def test_uri_like(pyls):
assert pyls.workspace.get_uri_like('file:///some-path', '/my/path') == 'file:///my/path'


def test_non_root_project(pyls):
repo_root = os.path.join(pyls.workspace.root, 'repo-root')
os.mkdir(repo_root)
project_root = os.path.join(repo_root, 'project-root')
os.mkdir(project_root)

with open(os.path.join(project_root, 'setup.py'), 'w+') as f:
f.write('# setup.py')

test_uri = 'file://' + os.path.join(project_root, 'hello/test.py')
pyls.workspace.put_document(test_uri, 'assert True')
test_doc = pyls.workspace.get_document(test_uri)
assert project_root in pyls.workspace.syspath_for_document(test_doc)

0 comments on commit 15e19cd

Please sign in to comment.