Skip to content

Commit

Permalink
Add support for flake8 per-file-ignores
Browse files Browse the repository at this point in the history
  • Loading branch information
brandonwillard committed Jan 17, 2021
1 parent a91a257 commit e0fe243
Show file tree
Hide file tree
Showing 5 changed files with 92 additions and 2 deletions.
1 change: 1 addition & 0 deletions pyls/config/flake8_conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
('ignore', 'plugins.flake8.ignore', list),
('max-line-length', 'plugins.flake8.maxLineLength', int),
('select', 'plugins.flake8.select', list),
('per-file-ignores', 'plugins.flake8.perFileIgnores', list),
]


Expand Down
5 changes: 4 additions & 1 deletion pyls/config/source.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,10 @@ def _get_opt(config, key, option, opt_type):


def _parse_list_opt(string):
return [s.strip() for s in string.split(",") if s.strip()]
if string.startswith("\n"):
return [s.strip().rstrip(",") for s in string.split("\n") if s.strip()]
else:
return [s.strip() for s in string.split(",") if s.strip()]


def _set_opt(config_dict, path, value):
Expand Down
13 changes: 12 additions & 1 deletion pyls/plugins/flake8_lint.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
import re
from subprocess import Popen, PIPE
from pyls import hookimpl, lsp
from pathlib import PurePath


log = logging.getLogger(__name__)
FIX_IGNORES_RE = re.compile(r'([^a-zA-Z0-9_,]*;.*(\W+||$))')
Expand All @@ -22,12 +24,21 @@ def pyls_lint(workspace, document):
settings = config.plugin_settings('flake8', document_path=document.path)
log.debug("Got flake8 settings: %s", settings)

ignores = settings.get("ignore", [])
per_file_ignores = settings.get("perFileIgnores")

if per_file_ignores:
for path in per_file_ignores:
file_pat, errors = path.split(":")
if PurePath(document.path).match(file_pat):
ignores.extend(errors.split(","))

opts = {
'config': settings.get('config'),
'exclude': settings.get('exclude'),
'filename': settings.get('filename'),
'hang-closing': settings.get('hangClosing'),
'ignore': settings.get('ignore'),
'ignore': ignores or None,
'max-line-length': settings.get('maxLineLength'),
'select': settings.get('select'),
}
Expand Down
1 change: 1 addition & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
install_requires = [
'configparser; python_version<"3.0"',
'future>=0.14.0; python_version<"3"',
'pathlib2>=2.3.5; python_version<"3"',
'backports.functools_lru_cache; python_version<"3.2"',
'jedi>=0.17.2,<0.18.0',
'python-jsonrpc-server>=0.4.0',
Expand Down
74 changes: 74 additions & 0 deletions test/plugins/test_flake8_lint.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,3 +84,77 @@ def test_flake8_executable_param(workspace):

call_args = popen_mock.call_args.args[0]
assert flake8_executable in call_args


def get_flake8_cfg_settings(workspace, config_str):
"""Write a ``setup.cfg``, load it in the workspace, and return the flake8 settings.
This function creates a ``setup.cfg``; you'll have to delete it yourself.
"""

with open(os.path.join(workspace.root_path, "setup.cfg"), "w+") as f:
f.write(config_str)

workspace.update_config({"pyls": {"configurationSources": ["flake8"]}})

return workspace._config.plugin_settings("flake8")


def test_flake8_multiline(workspace):
config_str = r"""[flake8]
exclude =
blah/,
file_2.py
"""

doc_str = "print('hi')\nimport os\n"

doc_uri = uris.from_fs_path(os.path.join(workspace.root_path, "blah/__init__.py"))
workspace.put_document(doc_uri, doc_str)

flake8_settings = get_flake8_cfg_settings(workspace, config_str)

assert "exclude" in flake8_settings
assert len(flake8_settings["exclude"]) == 2

with patch('pyls.plugins.flake8_lint.Popen') as popen_mock:
mock_instance = popen_mock.return_value
mock_instance.communicate.return_value = [bytes(), bytes()]

doc = workspace.get_document(doc_uri)
flake8_lint.pyls_lint(workspace, doc)

call_args = popen_mock.call_args.args[0]
assert call_args == ["flake8", "-", "--exclude=blah/,file_2.py"]

os.unlink(os.path.join(workspace.root_path, "setup.cfg"))


def test_flake8_per_file_ignores(workspace):
config_str = r"""[flake8]
ignores = F403
per-file-ignores =
**/__init__.py:F401,E402
test_something.py:E402,
exclude =
file_1.py
file_2.py
"""

doc_str = "print('hi')\nimport os\n"

doc_uri = uris.from_fs_path(os.path.join(workspace.root_path, "blah/__init__.py"))
workspace.put_document(doc_uri, doc_str)

flake8_settings = get_flake8_cfg_settings(workspace, config_str)

assert "perFileIgnores" in flake8_settings
assert len(flake8_settings["perFileIgnores"]) == 2
assert "exclude" in flake8_settings
assert len(flake8_settings["exclude"]) == 2

doc = workspace.get_document(doc_uri)
res = flake8_lint.pyls_lint(workspace, doc)
assert len(res) == 0

os.unlink(os.path.join(workspace.root_path, "setup.cfg"))

0 comments on commit e0fe243

Please sign in to comment.