Skip to content

Commit

Permalink
Add support for pyproject.toml as pylint config file (#107)
Browse files Browse the repository at this point in the history
Thanks! 馃挴
  • Loading branch information
michael-k committed Feb 10, 2020
1 parent f756f4c commit 965460c
Show file tree
Hide file tree
Showing 4 changed files with 90 additions and 23 deletions.
69 changes: 51 additions & 18 deletions pytest_pylint/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from pylint import lint
from pylint.config import PYLINTRC
import pytest
import toml

from .pylint_util import ProgrammaticReporter
from .util import get_rel_path, PyLintException, should_include_file
Expand Down Expand Up @@ -97,28 +98,60 @@ def pytest_configure(self, config):
# collection methods and not pyint's internal
if pylintrc_file and exists(pylintrc_file):
self.pylintrc_file = pylintrc_file
self.pylint_config = ConfigParser()
self.pylint_config.read(pylintrc_file)
if pylintrc_file.endswith(".toml"):
self._load_pyproject_toml(pylintrc_file)
else:
self.pylint_config = ConfigParser()
self.pylint_config.read(pylintrc_file)

try:
ignore_string = self.pylint_config.get('MASTER', 'ignore')
if ignore_string:
self.pylint_ignore = ignore_string.split(',')
except (NoSectionError, NoOptionError):
pass

try:
self.pylint_ignore_patterns = self.pylint_config.get(
'MASTER', 'ignore-patterns')
except (NoSectionError, NoOptionError):
pass

try:
self.pylint_msg_template = self.pylint_config.get(
'REPORTS', 'msg-template'
)
except (NoSectionError, NoOptionError):
pass

def _load_pyproject_toml(self, pylintrc_file):
with open(pylintrc_file, "r") as f_p:
try:
ignore_string = self.pylint_config.get('MASTER', 'ignore')
if ignore_string:
self.pylint_ignore = ignore_string.split(',')
except (NoSectionError, NoOptionError):
pass
content = toml.load(f_p)
except (TypeError, toml.decoder.TomlDecodeError):
return

try:
self.pylint_ignore_patterns = self.pylint_config.get(
'MASTER', 'ignore-patterns')
except (NoSectionError, NoOptionError):
pass
try:
self.pylint_config = content["tool"]["pylint"]
except KeyError:
return

try:
self.pylint_msg_template = self.pylint_config.get(
'REPORTS', 'msg-template'
)
except (NoSectionError, NoOptionError):
pass
master_section = {}
reports_section = {}
for key, value in self.pylint_config.items():
if not master_section and key.lower() == "master":
master_section = value
elif not reports_section and key.lower() == "reports":
reports_section = value

ignore = master_section.get("ignore")
if ignore:
self.pylint_ignore = ignore.split(",") if isinstance(ignore, str) \
else ignore

self.pylint_ignore_patterns = master_section.get("ignore-patterns") \
or []
self.pylint_msg_template = reports_section.get("msg-template")

def pytest_sessionfinish(self, session):
"""
Expand Down
41 changes: 37 additions & 4 deletions pytest_pylint/tests/test_pytest_pylint.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import os

import mock
import pytest


pytest_plugins = ('pytester',) # pylint: disable=invalid-name
Expand Down Expand Up @@ -65,6 +66,19 @@ def test_pylintrc_file(testdir):
assert 'Line too long (10/3)' in result.stdout.str()


def test_pylintrc_file_toml(testdir):
"""Verify that pyproject.toml can be used as a pylint rc file."""
rcfile = testdir.makefile('.toml', """
[tool.pylint.FORMAT]
max-line-length = "3"
""")
testdir.makepyfile("""import sys""")
result = testdir.runpytest(
'--pylint', '--pylint-rcfile={0}'.format(rcfile.strpath)
)
assert 'Line too long (10/3)' in result.stdout.str()


def test_pylintrc_file_beside_ini(testdir):
"""
Verify that a specified pylint rc file will work what placed into pytest
Expand Down Expand Up @@ -98,9 +112,21 @@ def test_pylintrc_file_beside_ini(testdir):
assert 'Line too long (10/3)' in result.stdout.str()


def test_pylintrc_ignore(testdir):
@pytest.mark.parametrize("rcformat", ("ini", "toml", "simple_toml"))
def test_pylintrc_ignore(testdir, rcformat):
"""Verify that a pylintrc file with ignores will work."""
rcfile = testdir.makefile('rc', """
if rcformat == "toml":
rcfile = testdir.makefile('toml', """
[tool.pylint.master]
ignore = ["test_pylintrc_ignore.py", "foo.py"]
""")
elif rcformat == "simple_toml":
rcfile = testdir.makefile('toml', """
[tool.pylint.MASTER]
ignore = "test_pylintrc_ignore.py,foo.py"
""")
else:
rcfile = testdir.makefile('rc', """
[MASTER]
ignore = test_pylintrc_ignore.py
Expand All @@ -112,9 +138,16 @@ def test_pylintrc_ignore(testdir):
assert 'collected 0 items' in result.stdout.str()


def test_pylintrc_msg_template(testdir):
@pytest.mark.parametrize("rcformat", ("ini", "toml"))
def test_pylintrc_msg_template(testdir, rcformat):
"""Verify that msg-template from pylintrc file is handled."""
rcfile = testdir.makefile('rc', """
if rcformat == "toml":
rcfile = testdir.makefile('toml', """
[tool.pylint.REPORTS]
msg-template = "start {msg_id} end"
""")
else:
rcfile = testdir.makefile('rc', """
[REPORTS]
msg-template=start {msg_id} end
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
packages=['pytest_pylint'],
entry_points={'pytest11': ['pylint = pytest_pylint.plugin']},
python_requires=">=3.5",
install_requires=['pytest>=5.0', 'pylint>=2.0.0'],
install_requires=['pytest>=5.0', 'pylint>=2.0.0', 'toml>=0.7.1'],
setup_requires=['pytest-runner'],
tests_require=['mock', 'coverage', 'pytest-pep8'],
classifiers=[
Expand Down
1 change: 1 addition & 0 deletions tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ deps =
pytest-pep8
coverage
mock
https://github.com/PyCQA/pylint/archive/master.tar.gz
commands =
coverage erase
coverage run -m py.test {posargs}
Expand Down

0 comments on commit 965460c

Please sign in to comment.