Skip to content

Commit

Permalink
Make pylint respect libraries installed into VIRTUAL_ENV
Browse files Browse the repository at this point in the history
Jedi respects VIRTUAL_ENV environment variable at finding out
libraries. Therefore, (virtualenv) runtime for pyls/jedi can be
separated from one for the target workspace.

On the other hand, pylint does not respect VIRTUAL_ENV, and might
cause unintentional "import-error" (E0401) for libraries installed in
such virtualenv, even though jedi can recognize them.

In order to make pylint respect libraries installed into VIRTUAL_ENV,
this commit uses Document.sys_path() instead of sys.path of current
pyls process, at spawning pylint. Document.sys_path() should respect
VIRTUAL_ENV, (original) PYTHONPATH, and so on, because it uses
Environment.get_sys_path() of jedi.

This commit chooses changing pyls instead of pylint, because pylint
uses "astroid" library to find out libraries imported in the target
file, and making astroid respect VIRTUAL_ENV seems very difficult (at
least, not so easy).
  • Loading branch information
flying-foozy committed Dec 12, 2019
1 parent 2cc8080 commit 86fa2a0
Showing 1 changed file with 11 additions and 1 deletion.
12 changes: 11 additions & 1 deletion pyls/plugins/pylint_lint.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,19 @@

if sys.version_info.major == 2:
from StringIO import StringIO

# subprocess.Popen() on Windows expects that env contains only
# "str" keys/values (= "bytes" for Python2.x, "unicode" for
# Python3.x), even though pyls treats all path values as "unicode"
# regardless of Python version
def stringify(u):
return u.encode('utf-8')
else:
from io import StringIO

def stringify(u):
return u

log = logging.getLogger(__name__)


Expand All @@ -33,7 +43,7 @@ def spawn_pylint(document, flags):
path = path.replace('\\', '/')

env = dict(os.environ)
env["PYTHONPATH"] = os.pathsep.join(sys.path)
env["PYTHONPATH"] = stringify(os.pathsep.join(document.sys_path()))

# Detect if we use Python as executable or not, else default to `python`
executable = sys.executable if "python" in sys.executable else "python"
Expand Down

0 comments on commit 86fa2a0

Please sign in to comment.