Skip to content

Commit

Permalink
feat: Configure comma separated values on the style file
Browse files Browse the repository at this point in the history
  • Loading branch information
andreoliwa committed Jan 11, 2019
1 parent b5d8ce7 commit 7ae6622
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 16 deletions.
13 changes: 13 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -110,3 +110,16 @@ To enforce that certain files should not exist in the project, you can add them
Multiple files can be configured as above.
The ``message`` is optional.

Comma separated values (setup.cfg)
----------------------------------

On ``setup.cfg``, some keys are lists of multiple values separated by commas, like ``flake8.ignore``.

On the style file, it's possible to indicate which key/value pairs should be treated as multiple values instead of an exact string.
Multiple keys can be added.

.. code-block:: ini
["setup.cfg"]
comma_separated_values = ["flake8.ignore", "isort.some_key", "another_section.another_key"]
9 changes: 6 additions & 3 deletions flake8_nitpick/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import logging
from configparser import ConfigParser
from io import StringIO
from typing import Optional, Tuple, Type, Any, Dict, Generator, List, MutableMapping, Union
from typing import Optional, Tuple, Type, Any, Dict, Generator, List, MutableMapping, Union, Set

import os
import dictdiffer
Expand Down Expand Up @@ -333,13 +333,16 @@ class SetupCfgChecker(BaseChecker):
file_name = "setup.cfg"
error_base_number = 320

COMMA_SEPARATED_KEYS = {"flake8.ignore"}
COMMA_SEPARATED_VALUES = "comma_separated_values"
comma_separated_values: Set[str]

def check_rules(self) -> YieldFlake8Error:
"""Check missing sections and missing key/value pairs in setup.cfg."""
if not self.file_path.exists():
return

self.comma_separated_values = set(self.file_toml.pop(self.COMMA_SEPARATED_VALUES, []))

setup_cfg = ConfigParser()
setup_cfg.read_file(self.file_path.open())

Expand Down Expand Up @@ -369,7 +372,7 @@ def check_rules(self) -> YieldFlake8Error:
def compare_different_keys(self, section, key, raw_expected: Any, raw_actual: Any) -> YieldFlake8Error:
"""Compare different keys, with special treatment when they are lists or numeric."""
combined = f"{section}.{key}"
if combined in self.COMMA_SEPARATED_KEYS:
if combined in self.comma_separated_values:
# The values might contain spaces
actual_set = {s.strip() for s in raw_actual.split(",")}
expected_set = {s.strip() for s in raw_expected.split(",")}
Expand Down
3 changes: 3 additions & 0 deletions nitpick-style.toml
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ ipdb = "*"
pylint = "*"
mypy = "*"

["setup.cfg"]
comma_separated_values = ["flake8.ignore"]

["setup.cfg".flake8]
# http://www.pydocstyle.org/en/2.1.1/error_codes.html
# Ignoring W503: https://github.com/ambv/black#line-breaks--binary-operators
Expand Down
24 changes: 21 additions & 3 deletions tests/helpers.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,19 @@
"""Test helpers."""
import os
from pathlib import Path
from pprint import pprint
from typing import List, Set

from _pytest.fixtures import FixtureRequest

from flake8_nitpick import NITPICK_STYLE_TOML, Flake8Error, NitpickChecker, PyProjectTomlChecker, SetupCfgChecker
from flake8_nitpick import (
ERROR_PREFIX,
NITPICK_STYLE_TOML,
Flake8Error,
NitpickChecker,
PyProjectTomlChecker,
SetupCfgChecker,
)
from tests.conftest import TEMP_ROOT_PATH


Expand Down Expand Up @@ -48,9 +56,9 @@ def lint(self, file_index: int = 0) -> "ProjectMock":
self.errors = set()
for flake8_error in self.original_errors:
line, col, message, class_ = flake8_error
assert line
assert line == 1
assert col == 0
assert message
assert message.startswith(ERROR_PREFIX)
assert class_ is NitpickChecker
self.errors.add(message)
return self
Expand All @@ -74,3 +82,13 @@ def setup_cfg(self, file_contents: str) -> "ProjectMock":
def pyproject_toml(self, file_contents: str):
"""Save pyproject.toml."""
return self.save_file(PyProjectTomlChecker.file_name, file_contents)

def assert_errors_contain(self, error: str) -> None:
"""Assert the error is in the error set."""
if error in self.errors:
return

print(f"Expected error:\n{error}")
print("\nAll errors:")
pprint(self.errors, width=150)
assert False
22 changes: 12 additions & 10 deletions tests/test_nitpick.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,27 +19,29 @@ def test_no_main_python_file_root_dir(request):
}


def test_comma_separated_keys(request):
"""Comma separated keys on setup.cfg."""
def test_comma_separated_keys_on_style_file(request):
"""Comma separated keys on the style file."""
project = (
ProjectMock(request)
.style(
"""
["setup.cfg".flake8]
ignore = "salt,ham,eggs"
["setup.cfg"]
comma_separated_values = ["food.eat"]
["setup.cfg".food]
eat = "salt,ham,eggs"
"""
)
.setup_cfg(
"""
[flake8]
ignore = spam,eggs,cheese
[food]
eat = spam,eggs,cheese
"""
)
.lint()
)
assert (
project.assert_errors_contain(
"""NIP322 File: setup.cfg: Missing values in key
[flake8]
ignore = ham,salt"""
in project.errors
[food]
eat = ham,salt"""
)

0 comments on commit 7ae6622

Please sign in to comment.