| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103 |
- """ py.test plugin for checking files with pylama. """
- from __future__ import absolute_import
- import pathlib
- from os import path as op
- import pytest
- from pylama.config import CURDIR
- from pylama.main import DEFAULT_FORMAT, check_paths, parse_options
- HISTKEY = "pylama/mtimes"
- def pytest_load_initial_conftests(early_config, *_):
- # Marks have to be registered before usage
- # to not fail with --strict command line argument
- early_config.addinivalue_line(
- "markers", "pycodestyle: Mark test as using pylama code audit tool."
- )
- def pytest_addoption(parser):
- group = parser.getgroup("general")
- group.addoption(
- "--pylama",
- action="store_true",
- help="perform some pylama code checks on .py files",
- )
- def pytest_sessionstart(session):
- config = session.config
- if config.option.pylama and getattr(config, "cache", None):
- config._pylamamtimes = config.cache.get(HISTKEY, {})
- def pytest_sessionfinish(session):
- config = session.config
- if hasattr(config, "_pylamamtimes"):
- config.cache.set(HISTKEY, config._pylamamtimes)
- def pytest_collect_file(path, parent):
- config = parent.config
- if config.option.pylama and path.ext == ".py":
- return PylamaFile.from_parent(parent, path=pathlib.Path(path))
- return None
- class PylamaError(Exception):
- """indicates an error during pylama checks."""
- class PylamaFile(pytest.File):
- def collect(self):
- return [PylamaItem.from_parent(self, name="pylama")]
- class PylamaItem(pytest.Item):
- def __init__(self, *args, **kwargs):
- super().__init__(*args, **kwargs)
- self.add_marker("pycodestyle")
- self.cache = None
- self._pylamamtimes = None
- def setup(self):
- if not getattr(self.config, "cache", None):
- return False
- self.cache = True
- self._pylamamtimes = self.fspath.mtime()
- pylamamtimes = self.config._pylamamtimes
- old = pylamamtimes.get(str(self.fspath), 0)
- if old == self._pylamamtimes:
- pytest.skip("file(s) previously passed Pylama checks")
- return True
- def runtest(self):
- errors = check_file(self.fspath)
- if errors:
- out = "\n".join(err.format(DEFAULT_FORMAT) for err in errors)
- raise PylamaError(out)
- # update mtime only if test passed
- # otherwise failures would not be re-run next time
- if self.cache:
- self.config._pylamamtimes[str(self.fspath)] = self._pylamamtimes
- def repr_failure(self, excinfo, style=None):
- if excinfo.errisinstance(PylamaError):
- return excinfo.value.args[0]
- return super().repr_failure(excinfo, style)
- def check_file(path):
- options = parse_options()
- path = op.relpath(str(path), CURDIR)
- return check_paths([path], options, rootdir=CURDIR)
- # pylama:ignore=D,E1002,W0212,F0001,C0115,C0116
|