Skip to content

Commit 01b1be2

Browse files
Add support for flake8 per-file-ignores
1 parent 5a13db1 commit 01b1be2

File tree

4 files changed

+90
-2
lines changed

4 files changed

+90
-2
lines changed

Diff for: pylsp/config/flake8_conf.py

+1
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
('ignore', 'plugins.flake8.ignore', list),
2929
('max-line-length', 'plugins.flake8.maxLineLength', int),
3030
('select', 'plugins.flake8.select', list),
31+
('per-file-ignores', 'plugins.flake8.perFileIgnores', list),
3132
]
3233

3334

Diff for: pylsp/config/source.py

+2
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,8 @@ def _get_opt(config, key, option, opt_type):
6969

7070

7171
def _parse_list_opt(string):
72+
if string.startswith("\n"):
73+
return [s.strip().rstrip(",") for s in string.split("\n") if s.strip()]
7274
return [s.strip() for s in string.split(",") if s.strip()]
7375

7476

Diff for: pylsp/plugins/flake8_lint.py

+13-2
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@
55
import logging
66
import os.path
77
import re
8-
from subprocess import Popen, PIPE
8+
from pathlib import PurePath
9+
from subprocess import PIPE, Popen
10+
911
from pylsp import hookimpl, lsp
1012

1113
log = logging.getLogger(__name__)
@@ -24,12 +26,21 @@ def pylsp_lint(workspace, document):
2426
settings = config.plugin_settings('flake8', document_path=document.path)
2527
log.debug("Got flake8 settings: %s", settings)
2628

29+
ignores = settings.get("ignore", [])
30+
per_file_ignores = settings.get("perFileIgnores")
31+
32+
if per_file_ignores:
33+
for path in per_file_ignores:
34+
file_pat, errors = path.split(":")
35+
if PurePath(document.path).match(file_pat):
36+
ignores.extend(errors.split(","))
37+
2738
opts = {
2839
'config': settings.get('config'),
2940
'exclude': settings.get('exclude'),
3041
'filename': settings.get('filename'),
3142
'hang-closing': settings.get('hangClosing'),
32-
'ignore': settings.get('ignore'),
43+
'ignore': ignores or None,
3344
'max-line-length': settings.get('maxLineLength'),
3445
'select': settings.get('select'),
3546
}

Diff for: test/plugins/test_flake8_lint.py

+74
Original file line numberDiff line numberDiff line change
@@ -85,3 +85,77 @@ def test_flake8_executable_param(workspace):
8585

8686
(call_args,) = popen_mock.call_args[0]
8787
assert flake8_executable in call_args
88+
89+
90+
def get_flake8_cfg_settings(workspace, config_str):
91+
"""Write a ``setup.cfg``, load it in the workspace, and return the flake8 settings.
92+
93+
This function creates a ``setup.cfg``; you'll have to delete it yourself.
94+
"""
95+
96+
with open(os.path.join(workspace.root_path, "setup.cfg"), "w+") as f:
97+
f.write(config_str)
98+
99+
workspace.update_config({"pylsp": {"configurationSources": ["flake8"]}})
100+
101+
return workspace._config.plugin_settings("flake8")
102+
103+
104+
def test_flake8_multiline(workspace):
105+
config_str = r"""[flake8]
106+
exclude =
107+
blah/,
108+
file_2.py
109+
"""
110+
111+
doc_str = "print('hi')\nimport os\n"
112+
113+
doc_uri = uris.from_fs_path(os.path.join(workspace.root_path, "blah/__init__.py"))
114+
workspace.put_document(doc_uri, doc_str)
115+
116+
flake8_settings = get_flake8_cfg_settings(workspace, config_str)
117+
118+
assert "exclude" in flake8_settings
119+
assert len(flake8_settings["exclude"]) == 2
120+
121+
with patch('pylsp.plugins.flake8_lint.Popen') as popen_mock:
122+
mock_instance = popen_mock.return_value
123+
mock_instance.communicate.return_value = [bytes(), bytes()]
124+
125+
doc = workspace.get_document(doc_uri)
126+
flake8_lint.pylsp_lint(workspace, doc)
127+
128+
call_args = popen_mock.call_args[0][0]
129+
assert call_args == ["flake8", "-", "--exclude=blah/,file_2.py"]
130+
131+
os.unlink(os.path.join(workspace.root_path, "setup.cfg"))
132+
133+
134+
def test_flake8_per_file_ignores(workspace):
135+
config_str = r"""[flake8]
136+
ignores = F403
137+
per-file-ignores =
138+
**/__init__.py:F401,E402
139+
test_something.py:E402,
140+
exclude =
141+
file_1.py
142+
file_2.py
143+
"""
144+
145+
doc_str = "print('hi')\nimport os\n"
146+
147+
doc_uri = uris.from_fs_path(os.path.join(workspace.root_path, "blah/__init__.py"))
148+
workspace.put_document(doc_uri, doc_str)
149+
150+
flake8_settings = get_flake8_cfg_settings(workspace, config_str)
151+
152+
assert "perFileIgnores" in flake8_settings
153+
assert len(flake8_settings["perFileIgnores"]) == 2
154+
assert "exclude" in flake8_settings
155+
assert len(flake8_settings["exclude"]) == 2
156+
157+
doc = workspace.get_document(doc_uri)
158+
res = flake8_lint.pylsp_lint(workspace, doc)
159+
assert not res
160+
161+
os.unlink(os.path.join(workspace.root_path, "setup.cfg"))

0 commit comments

Comments
 (0)