Skip to content

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
  • Loading branch information
klen committed Sep 7, 2016
2 parents a0b0fe6 + 4695854 commit 38dd37b
Show file tree
Hide file tree
Showing 18 changed files with 73 additions and 61 deletions.
2 changes: 1 addition & 1 deletion .bumpversion.cfg
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[bumpversion]
commit = True
current_version = 7.0.9
current_version = 7.1.0
files = pylama/__init__.py
tag = True
tag_name = {new_version}
Expand Down
5 changes: 3 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,20 @@ env:
- TOXENV=py26
- TOXENV=py27
- TOXENV=py33
- TOXENV=py35
- TOXENV=cov

branches:
only:
- master
- develop

install: pip install --quiet --use-mirrors tox
install: pip install tox

script: tox

after_script:
- if [ $TOXENV == "cov" ]; then
pip install --quiet --use-mirrors coveralls;
pip install coveralls;
coveralls;
fi
4 changes: 2 additions & 2 deletions AUTHORS
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ Contributors:
* Daniel O'onnell' (https://github.com/mruwnik)
* Fábio C. Barrionuevo da Luz (https://github.com/luzfcb)
* Grzegorz Śliwiński (https://github.com/fizyk)
* Grzegorz Śliwiński (https://github.com/fizyk)
* Jarek Śmiejczak (https://github.com/jarekps)
* Jarek Śmiejczak (https://github.com/jotes)
* Jens Persson (https://github.com/MrShark)
* Johan Bloemberg (https://github.com/aequitas)
* Serg Baburin (https://github.com/gmist)
* Tomasz Karbownicki (https://github.com/trojkat)
* lukaszpiotr (https://github.com/lukaszpiotr)
6 changes: 3 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -64,13 +64,13 @@ upload: clean
# =============

.PHONY: t
t:
t test:
@py.test -sx tests.py

.PHONY: audit
audit:
python -m "pylama.main"
@python -m "pylama.main"

.PHONY: docs
docs: docs
python setup.py build_sphinx --source-dir=docs/ --build-dir=docs/_build --all-files
@python setup.py build_sphinx --source-dir=docs/ --build-dir=docs/_build --all-files
20 changes: 10 additions & 10 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
Code audit tool for Python and JavaScript. Pylama wraps these tools:

* PEP8_ © 2012-2013, Florent Xicluna;
* PEP257_ © 2012, GreenSteam, <http://greensteam.dk/>
* pydocstyle_ (formerly pep257 by Vladimir Keleshev) © 2014, Amir Rachum;
* PyFlakes_ © 2005-2013, Kevin Watters;
* Mccabe_ © Ned Batchelder;
* Pylint_ © 2013, Logilab (should be installed 'pylama_pylint' module);
Expand Down Expand Up @@ -108,12 +108,12 @@ Command line options
[--ignore IGNORE] [--skip SKIP] [--report REPORT] [--hook]
[--async] [--options OPTIONS] [--force] [--abspath]
[paths [paths ...]]

Code audit tool for python.

positional arguments:
paths Paths to files or directories for code check.

optional arguments:
-h, --help show this help message and exit
--verbose, -v Verbose mode.
Expand All @@ -125,7 +125,7 @@ Command line options
--sort SORT Sort result by error types. Ex. E,W,D
--linters LINTERS, -l LINTERS
Select linters. (comma-separated). Choices are
mccabe,pep8,pyflakes,pep257.
mccabe,pep8,pyflakes,pydocstyle.
--ignore IGNORE, -i IGNORE
Ignore errors and warnings. (comma-separated)
--skip SKIP Skip files by masks (comma-separated, Ex.
Expand Down Expand Up @@ -262,7 +262,7 @@ Check files with pylama ::

pytest --pylama ...

Recomended way to settings pyalam options when using pytest — configuration
Recomended way to settings pylama options when using pytest — configuration
files (see below).


Expand All @@ -280,7 +280,7 @@ In 'setup.py' should be defined 'pylama.linter' entry point. ::
'pylama.linter': ['lintername = pylama_lintername.main:Linter'],
}
# ...
)
)

'Linter' should be instance of 'pylama.lint.Linter' class.
Must implemented two methods:
Expand All @@ -302,7 +302,7 @@ setup.py: ::
'pylama.linter': ['wow = pylama_wow.main:Linter'],
}
# ...
)
)

pylama_wow.py: ::

Expand Down Expand Up @@ -370,10 +370,10 @@ Licensed under a `BSD license`_.

.. _links:

.. _AUTHORS: https://github.com/klen/pylama/blob/develop/AUTHORS
.. _AUTHORS: https://github.com/klen/pylama/blob/develop/AUTHORS
.. _BSD license: http://www.linfo.org/bsdlicense.html
.. _Mccabe: http://nedbatchelder.com/blog/200803/python_code_complexity_microtool.html
.. _PEP257: https://github.com/GreenSteam/pep257
.. _pydocstyle: https://github.com/PyCQA/pydocstyle/
.. _PEP8: https://github.com/jcrocholl/pep8
.. _PyFlakes: https://github.com/pyflakes/pyflakes
.. _Pylint: http://pylint.org
Expand Down
2 changes: 1 addition & 1 deletion pylama/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
:license: BSD, see LICENSE for more details.
"""

__version__ = "7.0.9"
__version__ = "7.1.0"
__project__ = "pylama"
__author__ = "Kirill Klenov <horneds@gmail.com>"
__license__ = "GNU LGPL"
17 changes: 9 additions & 8 deletions pylama/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,14 +43,14 @@ def __repr__(self):


def split_csp_str(s):
""" Split commaseparated string.
""" Split comma separated string into unique values, keeping their order.
:returns: list of splitted values
"""
if isinstance(s, (list, tuple)):
return s
return list(set(i for i in s.strip().split(',') if i))
seen = set()
l = s if isinstance(s, (list, tuple)) else s.strip().split(',')
return [x for x in l if x and not (x in seen or seen.add(x))]


def parse_linters(linters):
Expand Down Expand Up @@ -81,8 +81,9 @@ def parse_linters(linters):
version='%(prog)s ' + __version__)

PARSER.add_argument(
"--format", "-f", default=_Default('pep8'), choices=['pep8', 'pylint'],
help="Choose errors format (pep8, pylint).")
"--format", "-f", default=_Default('pep8'),
choices=['pep8', 'pylint', 'parsable'],
help="Choose errors format (pep8, pylint, parsable).")

PARSER.add_argument(
"--select", "-s", default=_Default(''), type=split_csp_str,
Expand Down Expand Up @@ -183,8 +184,8 @@ def parse_options(args=None, config=True, rootdir=CURDIR, **overrides): # noqa
options.file_params[mask] = dict(opts)

# Postprocess options
opts = dict(options.__dict__.items())
for name, value in opts.items():
for name in options.__dict__:
value = getattr(options, name)
if isinstance(value, _Default):
setattr(options, name, process_value(name, value.value))

Expand Down
3 changes: 2 additions & 1 deletion pylama/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,8 @@ def run(path='', code=None, rootdir=CURDIR, options=None):
except SyntaxError as e:
LOGGER.debug("SyntaxError %s", e)
errors.append(
Error(linter=lname, lnum=e.lineno, col=e.offset, text=e.args[0],
Error(linter='pylama', lnum=e.lineno, col=e.offset,
text='E0100 SyntaxError: {}'.format(e.args[0]),
filename=path))

except Exception as e: # noqa
Expand Down
13 changes: 10 additions & 3 deletions pylama/errors.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
""" Don't duplicate same errors from different linters. """

import re
from collections import defaultdict


PATTERN_NUMBER = re.compile(r'^[A-Z]\d+$')


DUPLICATES = (

# multiple statements on one line
Expand Down Expand Up @@ -48,6 +51,7 @@
[('pylint', 'W00401'), ('pyflakes', 'W0401')],

# module docstring
[('pydocstyle', 'D100'), ('pylint', 'C0111')],
[('pep257', 'D100'), ('pylint', 'C0111')],

)
Expand All @@ -72,12 +76,15 @@ class Error(object):
""" Store an error's information. """

def __init__(self, linter="", col=1, lnum=1, type="E",
text="unknown error", filename="", **kwargs):
text="unknown error", filename="", number="", **kwargs):
""" Init error information with default values. """
text = ' '.join(str(text).strip().split('\n'))
if linter:
text = "%s [%s]" % (text, linter)
number = text.split(' ', 1)[0]
number = number or text.split(' ', 1)[0]
if not PATTERN_NUMBER.match(number):
number = ""

self._info = dict(linter=linter, col=col, lnum=lnum, type=type[:1],
text=text, filename=filename, number=number)

Expand Down
5 changes: 3 additions & 2 deletions pylama/lint/extensions.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,9 @@
pass

try:
from pylama.lint.pylama_pep257 import Linter
LINTERS['pep257'] = Linter()
from pylama.lint.pylama_pydocstyle import Linter
LINTERS['pep257'] = Linter() # for compatibility
LINTERS['pydocstyle'] = Linter()
except ImportError:
pass

Expand Down
5 changes: 1 addition & 4 deletions pylama/lint/pylama_mccabe.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,7 @@ def run(path, code=None, params=None, **meta):
:return list: List of errors.
"""
try:
tree = compile(code, path, "exec", ast.PyCF_ONLY_AST)
except SyntaxError as exc:
return [{'lnum': exc.lineno, 'text': 'Invalid syntax: %s' % exc.text.strip()}]
tree = compile(code, path, "exec", ast.PyCF_ONLY_AST)

McCabeChecker.max_complexity = int(params.get('complexity', 10))
return [
Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
"""PEP257 support."""
"""pydocstyle support."""

from pep257 import PEP257Checker
from pydocstyle import PEP257Checker

from pylama.lint import Linter as Abstract


class Linter(Abstract):

"""Check PEP257 errors."""
"""Check pydocstyle errors."""

@staticmethod
def run(path, code=None, **meta):
"""PEP257 code checking.
"""pydocstyle code checking.
:return list: List of errors.
"""
return [
{'lnum': e.line, 'text': e.message, 'type': 'D'}
{'lnum': e.line, 'text': e.message, 'type': 'D', 'number': e.code}
for e in PEP257Checker().check_source(code, path)
]
1 change: 1 addition & 0 deletions pylama/lint/pylama_pyflakes.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
checker.messages.RedefinedInListComp.message = "W0621 list comprehension redefines %r from line %r"
checker.messages.ImportShadowedByLoopVar.message = "W0621 import %r from line %r shadowed by loop variable"
checker.messages.ImportStarUsed.message = "W0401 'from %s import *' used; unable to detect undefined names"
checker.messages.ImportStarUsage.message = "W0401 '%s may be undefined, or defined from star imports: %s'"
checker.messages.UndefinedName.message = "E0602 undefined name %r"
checker.messages.DoctestSyntaxError.message = "W0511 syntax error in doctest"
checker.messages.UndefinedExport.message = "E0603 undefined name %r in __all__"
Expand Down
7 changes: 5 additions & 2 deletions pylama/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,9 +81,12 @@ def process_paths(options, candidates=None, error=True):
"""Process files and log errors."""
errors = check_path(options, rootdir=CURDIR, candidates=candidates)

pattern = "%(filename)s:%(lnum)s:%(col)s: %(text)s"
if options.format == 'pylint':
if options.format == 'pep8':
pattern = "%(filename)s:%(lnum)s:%(col)s: %(text)s"
elif options.format == 'pylint':
pattern = "%(filename)s:%(lnum)s: [%(type)s] %(text)s"
else: # 'parsable'
pattern = "%(filename)s:%(lnum)s:%(col)s: [%(type)s] %(text)s"

for er in errors:
if options.abspath:
Expand Down
8 changes: 4 additions & 4 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Test requirements

mccabe == 0.4.0
pep257 == 0.7.0
pep8 == 1.7.0
pyflakes == 1.0.0
mccabe >= 0.5.2
pydocstyle >= 1.0.0
pep8 >= 1.7.0
pyflakes >= 1.3.0
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
long_description=_read('README.rst'),
platforms=('Any'),
zip_safe=False,
keywords='pylint pep8 pyflakes mccabe linter qa pep257'.split(),
keywords='pylint pep8 pyflakes mccabe linter qa pep257 pydocstyle'.split(),

author='Kirill Klenov',
author_email='horneds@gmail.com',
Expand Down
20 changes: 10 additions & 10 deletions tests.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
import os.path as op

from pylama.async import check_async
from pylama.config import parse_options, get_config
from pylama.core import (
filter_errors, parse_modeline, prepare_params, run)
from pylama.core import filter_errors, parse_modeline, prepare_params, run
from pylama.errors import Error, remove_duplicates
from pylama.hook import git_hook, hg_hook
from pylama.lint.extensions import LINTERS
from pylama.main import shell, check_path
from pylama.async import check_async


def test_filter_errors():
assert list(filter_errors([Error(text='E')], select=['E'], ignore=['E101']))
assert not list(filter_errors([Error(text='W')], select=['W100'], ignore=['W']))
assert list(filter_errors([Error(text='E1')], select=['E'], ignore=['E101']))
assert not list(filter_errors([Error(text='W1')], select=['W100'], ignore=['W']))


def test_remove_duplicates():
Expand Down Expand Up @@ -75,8 +75,8 @@ def test_pep8():
assert len(errors) == 11


def test_pep257():
options = parse_options(linters=['pep257'])
def test_pydocstyle():
options = parse_options(linters=['pydocstyle'])
errors = run('dummy.py', options=options)
assert errors

Expand All @@ -102,7 +102,7 @@ def test_sort():
def test_ignore_select():
options = parse_options()
options.ignore = ['E301', 'D102']
options.linters = ['pep8', 'pep257', 'pyflakes', 'mccabe']
options.linters = ['pep8', 'pydocstyle', 'pyflakes', 'mccabe']
errors = run('dummy.py', options=options)
assert len(errors) == 16

Expand Down Expand Up @@ -142,9 +142,9 @@ def test_config():
assert not options.verbose
assert options.paths == ['pylama']

options = parse_options(['-l', 'pep257,pep8', '-i', 'E'])
options = parse_options(['-l', 'pydocstyle,pep8', '-i', 'E'])
linters, _ = zip(*options.linters)
assert set(linters) == set(['pep257', 'pep8'])
assert set(linters) == set(['pydocstyle', 'pep8'])
assert options.ignore == ['E']

options = parse_options('-o dummy dummy.py'.split())
Expand Down

0 comments on commit 38dd37b

Please sign in to comment.