From f955a98b718ab111ff13e8e125a63838dbc111d5 Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Wed, 30 Jan 2019 19:33:27 -0800 Subject: [PATCH] Improve error message for malformed per-file-ignores --- src/flake8/utils.py | 21 +++++++++++++++++++-- tests/integration/test_main.py | 27 +++++++++++++++++++++++++++ tests/unit/test_utils.py | 3 ++- 3 files changed, 48 insertions(+), 3 deletions(-) diff --git a/src/flake8/utils.py b/src/flake8/utils.py index ae0d060..70b45e0 100644 --- a/src/flake8/utils.py +++ b/src/flake8/utils.py @@ -12,6 +12,8 @@ from typing import Callable, Dict, Generator # noqa: F401 (until flake8 3.7) from typing import List, Pattern, Sequence # noqa: F401 (until flake8 3,7) from typing import Tuple, Union # noqa: F401 (until flake8 3.7) +from flake8 import exceptions + if False: # `typing.TYPE_CHECKING` was introduced in 3.5.2 from flake8.plugins.manager import Plugin # noqa: F401 (until flake8 3.7) @@ -109,6 +111,21 @@ def parse_files_to_codes_mapping(value): # noqa: C901 State.filenames = [] State.codes = [] + def _unexpected_token(): + # type: () -> exceptions.ExecutionError + + def _indent(s): + # type: (str) -> str + return " " + s.strip().replace("\n", "\n ") + + return exceptions.ExecutionError( + "Expected `per-file-ignores` to be a mapping from file exclude " + "patterns to ignore codes.\n\n" + "Configured `per-file-ignores` setting:\n\n{}".format( + _indent(value) + ) + ) + for token in _tokenize_files_to_codes_mapping(value): # legal in any state: separator sets the sep bit if token.tp in {_COMMA, _WS}: @@ -122,7 +139,7 @@ def parse_files_to_codes_mapping(value): # noqa: C901 State.filenames.append(token.src) State.seen_sep = False else: - raise ValueError("Unexpected token: {}".format(token)) + raise _unexpected_token() # looking for codes else: if token.tp == _EOF: @@ -135,7 +152,7 @@ def parse_files_to_codes_mapping(value): # noqa: C901 State.filenames.append(token.src) State.seen_sep = False else: - raise ValueError("Unexpected token: {}".format(token)) + raise _unexpected_token() return ret diff --git a/tests/integration/test_main.py b/tests/integration/test_main.py index 56f9414..ba4dd56 100644 --- a/tests/integration/test_main.py +++ b/tests/integration/test_main.py @@ -58,3 +58,30 @@ t.py:2:1: F401 'sys' imported but unused 2 F401 'os' imported but unused ''' assert err == '' + + +def test_malformed_per_file_ignores_error(tmpdir, capsys): + """Test the error message for malformed `per-file-ignores`.""" + setup_cfg = '''\ +[flake8] +per-file-ignores = + incorrect/* + values/* +''' + + with tmpdir.as_cwd(): + tmpdir.join('setup.cfg').write(setup_cfg) + + app = application.Application() + app.run(['.']) + + out, err = capsys.readouterr() + assert out == '''\ +There was a critical error during execution of Flake8: +Expected `per-file-ignores` to be a mapping from file exclude patterns to ignore codes. + +Configured `per-file-ignores` setting: + + incorrect/* + values/* +''' # noqa: E501 diff --git a/tests/unit/test_utils.py b/tests/unit/test_utils.py index b0eac9a..4b70918 100644 --- a/tests/unit/test_utils.py +++ b/tests/unit/test_utils.py @@ -4,6 +4,7 @@ import os import mock import pytest +from flake8 import exceptions from flake8 import utils from flake8.plugins import manager as plugin_manager @@ -111,7 +112,7 @@ def test_parse_files_to_codes_mapping(value, expected): ) def test_invalid_file_list(value): """Test parsing of invalid files-to-codes mappings.""" - with pytest.raises(ValueError): + with pytest.raises(exceptions.ExecutionError): utils.parse_files_to_codes_mapping(value)