diff --git a/pylsp/plugins/pylint_lint.py b/pylsp/plugins/pylint_lint.py index 459afbe3..452f45b9 100644 --- a/pylsp/plugins/pylint_lint.py +++ b/pylsp/plugins/pylint_lint.py @@ -10,7 +10,6 @@ from subprocess import Popen, PIPE import os -from pylint.epylint import py_run from pylsp import hookimpl, lsp try: @@ -85,20 +84,21 @@ def lint(cls, document, is_saved, flags=''): # save. return cls.last_diags[document.path] - # py_run will call shlex.split on its arguments, and shlex.split does - # not handle Windows paths (it will try to perform escaping). Turn - # backslashes into forward slashes first to avoid this issue. - path = document.path - if sys.platform.startswith('win'): - path = path.replace('\\', '/') - - pylint_call = '{} -f json {}'.format(path, flags) - log.debug("Calling pylint with '%s'", pylint_call) - json_out, err = py_run(pylint_call, return_std=True) - - # Get strings - json_out = json_out.getvalue() - err = err.getvalue() + cmd = [ + 'python', + '-c', + 'import sys; from pylint.lint import Run; Run(sys.argv[1:])', + '-f', + 'json', + document.path + ] + (str(flags).split(' ') if flags else []) + log.debug("Calling pylint with '%s'", ' '.join(cmd)) + + with Popen(cmd, stdout=PIPE, stderr=PIPE, + cwd=document._workspace.root_path, universal_newlines=True) as process: + process.wait() + json_out = process.stdout.read() + err = process.stderr.read() if err != '': log.error("Error calling pylint: '%s'", err) diff --git a/test/plugins/test_pylint_lint.py b/test/plugins/test_pylint_lint.py index 4e637819..3eae8914 100644 --- a/test/plugins/test_pylint_lint.py +++ b/test/plugins/test_pylint_lint.py @@ -3,11 +3,12 @@ # Copyright 2021- Python Language Server Contributors. import contextlib +from pathlib import Path import os import tempfile from pylsp import lsp, uris -from pylsp.workspace import Document +from pylsp.workspace import Document, Workspace from pylsp.plugins import pylint_lint DOC_URI = uris.from_fs_path(__file__) @@ -90,8 +91,9 @@ def test_lint_free_pylint(config, workspace): # Can't use temp_document because it might give us a file that doesn't # match pylint's naming requirements. We should be keeping this file clean # though, so it works for a test of an empty lint. + ws = Workspace(str(Path(__file__).absolute().parents[2]), workspace._endpoint) assert not pylint_lint.pylsp_lint( - config, workspace, Document(uris.from_fs_path(__file__), workspace), True) + config, ws, Document(uris.from_fs_path(__file__), ws), True) def test_lint_caching(workspace):