From 047af22e927cb2dc9504d361840925ab3bc89164 Mon Sep 17 00:00:00 2001 From: Stephen Moore Date: Mon, 12 Dec 2022 20:58:32 +1100 Subject: [PATCH] Make flake8 respect configuration * ensure flake8 is run from the correct directory * make flake8 aware of the filename being linted --- pylsp/plugins/flake8_lint.py | 9 +++-- test/plugins/test_flake8_lint.py | 62 +++++++++++++++++++++++++++++++- 2 files changed, 68 insertions(+), 3 deletions(-) diff --git a/pylsp/plugins/flake8_lint.py b/pylsp/plugins/flake8_lint.py index 94a3c2af..3a779db0 100644 --- a/pylsp/plugins/flake8_lint.py +++ b/pylsp/plugins/flake8_lint.py @@ -92,6 +92,9 @@ def run_flake8(flake8_executable, args, document): args = [(i if not i.startswith('--ignore=') else FIX_IGNORES_RE.sub('', i)) for i in args if i is not None] + if document.path and document.path.startswith(document._workspace.root_path): + args.extend(["--stdin-display-name", os.path.relpath(document.path, document._workspace.root_path)]) + # if executable looks like a path resolve it if not os.path.isfile(flake8_executable) and os.sep in flake8_executable: flake8_executable = os.path.abspath( @@ -102,12 +105,14 @@ def run_flake8(flake8_executable, args, document): try: cmd = [flake8_executable] cmd.extend(args) - p = Popen(cmd, stdin=PIPE, stdout=PIPE, stderr=PIPE) + p = Popen(cmd, stdin=PIPE, stdout=PIPE, stderr=PIPE, cwd=document._workspace.root_path) except IOError: log.debug("Can't execute %s. Trying with '%s -m flake8'", flake8_executable, sys.executable) cmd = [sys.executable, '-m', 'flake8'] cmd.extend(args) - p = Popen(cmd, stdin=PIPE, stdout=PIPE, stderr=PIPE) # pylint: disable=consider-using-with + p = Popen( # pylint: disable=consider-using-with + cmd, stdin=PIPE, stdout=PIPE, stderr=PIPE, cwd=document._workspace.root_path + ) (stdout, stderr) = p.communicate(document.source.encode()) if stderr: log.error("Error while running flake8 '%s'", stderr.decode()) diff --git a/test/plugins/test_flake8_lint.py b/test/plugins/test_flake8_lint.py index 6e162e8f..6a84f696 100644 --- a/test/plugins/test_flake8_lint.py +++ b/test/plugins/test_flake8_lint.py @@ -3,6 +3,7 @@ import tempfile import os +from textwrap import dedent from unittest.mock import patch from pylsp import lsp, uris from pylsp.plugins import flake8_lint @@ -59,6 +60,63 @@ def test_flake8_lint(workspace): os.remove(name) +def test_flake8_respecting_configuration(workspace): + docs = [ + ("src/__init__.py", ""), + ("src/a.py", DOC), + ("src/b.py", "import os"), + ("setup.cfg", dedent(""" + [flake8] + ignore = E302,W191 + per-file-ignores = + src/a.py:F401 + src/b.py:W292 + """)) + ] + + made = {} + for rel, contents in docs: + location = os.path.join(workspace.root_path, rel) + made[rel] = {"uri": uris.from_fs_path(location)} + + os.makedirs(os.path.dirname(location), exist_ok=True) + with open(location, "w", encoding="utf-8") as fle: + fle.write(contents) + + workspace.put_document(made[rel]["uri"], contents) + made[rel]["document"] = workspace._docs[made[rel]["uri"]] + + diags = flake8_lint.pylsp_lint(workspace, made["src/a.py"]["document"]) + assert diags == [ + { + "source": "flake8", + "code": "F841", + "range": { + "start": {"line": 5, "character": 1}, + "end": {"line": 5, "character": 11}, + }, + "message": "F841 local variable 'a' is assigned to but never used", + "severity": 1, + "tags": [1], + }, + ] + + diags = flake8_lint.pylsp_lint(workspace, made["src/b.py"]["document"]) + assert diags == [ + { + "source": "flake8", + "code": "F401", + "range": { + "start": {"line": 0, "character": 0}, + "end": {"line": 0, "character": 9}, + }, + "message": "F401 'os' imported but unused", + "severity": 1, + "tags": [1], + } + ] + + def test_flake8_config_param(workspace): with patch('pylsp.plugins.flake8_lint.Popen') as popen_mock: mock_instance = popen_mock.return_value @@ -126,7 +184,9 @@ def test_flake8_multiline(workspace): flake8_lint.pylsp_lint(workspace, doc) call_args = popen_mock.call_args[0][0] - assert call_args == ["flake8", "-", "--exclude=blah/,file_2.py"] + + init_file = os.path.join("blah", "__init__.py") + assert call_args == ["flake8", "-", "--exclude=blah/,file_2.py", "--stdin-display-name", init_file] os.unlink(os.path.join(workspace.root_path, "setup.cfg"))