diff --git a/.hgignore b/.hgignore new file mode 100644 index 0000000..69a001c --- /dev/null +++ b/.hgignore @@ -0,0 +1,5 @@ +.*\.egg-info +build +dist +.*\.pyc +\.tox diff --git a/pytest_pep8.py b/pytest_pep8.py new file mode 100644 index 0000000..e006885 --- /dev/null +++ b/pytest_pep8.py @@ -0,0 +1,52 @@ +import pep8 +import py, pytest + +def pytest_addoption(parser): + group = parser.getgroup("general") + group.addoption('--pep8', action='store_true', + help="perform pep8 sanity checks on .py files") + +def pytest_collect_file(path, parent): + if parent.config.option.pep8 and path.ext == '.py': + return Pep8Item(path, parent) + +class Pep8Error(Exception): + """ indicates an error during pep8 checks. """ + +class Pep8Item(pytest.Item, pytest.File): + def runtest(self): + call = py.io.StdCapture.call + found_errors, out, err = call(check_file, self.fspath) + if found_errors: + raise Pep8Error(out, err) + + def repr_failure(self, excinfo): + if excinfo.errisinstance(Pep8Error): + return excinfo.value.args[0] + return super(Pep8Item, self).repr_failure(excinfo) + + def reportinfo(self): + return (self.fspath, -1, "PEP8-check") + +def check_file(path): + pep8.process_options(['pep8', + # ignore list taken from moin + '--ignore=E202,E221,E222,E241,E301,E302,E401,E501,E701,W391,W601,W602', + '--show-source', + '--repeat', + 'dummy file', + ]) + checker = PyTestChecker(str(path)) + #XXX: bails out on death + error_count = checker.check_all() + ignored = checker.ignored_errors + return max(error_count - ignored, 0) + +class PyTestChecker(pep8.Checker): + ignored_errors = 0 + def report_error(self, line_number, offset, text, check): + # XXX hack + if pep8.ignore_code(text[:4]): + self.ignored_errors += 1 + pep8.Checker.report_error(self, line_number, offset, text, check) + diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..0e0fb46 --- /dev/null +++ b/setup.py @@ -0,0 +1,44 @@ +""" +py.test plugin for checking PEP8 source code compliance using the pep8 module. + +Usage +--------- + +install via:: + + easy_install pytest-pep8 # or + pip install pytest-pep8 + +and then type:: + + py.test --pep8 + +to activate source code checking. Every file ending in ``.py`` will checked +and you can restrict it like this:: + + py.test --pep8 mysourcedir # or + py.test --pep8 mysourcedir/somefile.py + +Notes +------------- + +The repository of this plugin is at http://bitbucket.org/hpk42/pytest-pep8 + +For more info on py.test see http://pytest.org + +The code is partially based on Ronny Pfannschmidt's pytest-codecheckers plugin. +""" + +from setuptools import setup +setup( + name='pytest-pep8', + description='pytest plugin to check source code against PEP8 requirements', + long_description=__doc__, + version="0.5", + author='Holger Krekel and Ronny Pfannschmidt', + author_email='holger.krekel@gmail.com', + url='http://bitbucket.org/hpk42/pytest-pep8/', + py_modules=['pytest_pep8'], + entry_points={'pytest11': [ 'pep8 = pytest_pep8'],}, + install_requires=['pytest>=2.0', 'pep8', ], +) diff --git a/test_pep8.py b/test_pep8.py new file mode 100644 index 0000000..8df999e --- /dev/null +++ b/test_pep8.py @@ -0,0 +1,30 @@ + +pytest_plugins = "pytester", + +def test_simple(testdir): + testdir.makepyfile(""" + class AClass: + pass + + + + # too many spaces + """) + result = testdir.runpytest("--pep8") + result.stdout.fnmatch_lines([ + "*W293*", + ]) + assert result.ret != 0 + +def test_ok_verbose(testdir): + p = testdir.makepyfile(""" + class AClass: + pass + """) + p = p.write(p.read() + "\n") + result = testdir.runpytest("--pep8", "--verbose") + result.stdout.fnmatch_lines([ + "*test_ok_verbose*PEP8-check*", + ]) + assert result.ret == 0 + diff --git a/tox.ini b/tox.ini new file mode 100644 index 0000000..353a1bf --- /dev/null +++ b/tox.ini @@ -0,0 +1,13 @@ +[tox] +indexserver = + testrun = http://pypi.testrun.org + default = http://pypi.python.org/simple + pypi = http://pypi.python.org/simple + +[testenv] +deps= + pytest + pep8 + +commands = + py.test --junitxml={envlogdir}/junit-{envname}.xml []