Skip to content

Commit 35d5349

Browse files
committed
Update pylama
1 parent f756847 commit 35d5349

84 files changed

Lines changed: 307 additions & 29 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

pylibs/autopep8.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@
5454
import difflib
5555
import tempfile
5656

57-
from pylama.checkers import pep8
57+
from pylama.lint.pylama_pep8 import pep8
5858

5959

6060
try:

pylibs/pylama/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
66
"""
77

8-
version_info = 1, 5, 3
8+
version_info = 2, 0, 1
99

1010
__version__ = version = '.'.join(map(str, version_info))
1111
__project__ = __name__

pylibs/pylama/checkers/pylint/logilab/__init__.py

Whitespace-only changes.

pylibs/pylama/config.py

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,23 @@
11
""" Parse arguments from command line and configuration files. """
22
import fnmatch
3-
import logging
4-
from argparse import ArgumentParser, Namespace as Options
53
from os import getcwd, path
64
from re import compile as re
75

8-
from . import version, utils
9-
from .core import DEFAULT_LINTERS, LOGGER, STREAM
6+
import logging
7+
from argparse import ArgumentParser, Namespace as Options
8+
9+
from . import version
10+
from .core import LOGGER, STREAM
1011
from .inirama import Namespace
12+
from .lint import LINTERS
13+
1114

15+
#: A default checkers
16+
DEFAULT_LINTERS = 'pep8', 'pyflakes', 'mccabe'
1217

18+
#: A default complexity for mccabe checker
1319
DEFAULT_COMPLEXITY = 10
20+
1421
CURDIR = getcwd()
1522
DEFAULT_INI_PATH = path.join(CURDIR, 'pylama.ini')
1623

@@ -30,7 +37,7 @@ def parse_options(
3037
async=_Default(async), format=_Default('pep8'),
3138
select=_Default(select), ignore=_Default(ignore),
3239
report=_Default(None), verbose=_Default(False),
33-
linters=_Default(linters), complexity=_Default(complexity),
40+
linters=_Default(','.join(linters)), complexity=_Default(complexity),
3441
options=_Default(options))
3542

3643
if not (args is None):
@@ -114,12 +121,19 @@ def get_parser():
114121
"--select", "-s", default=_Default(''), type=split_csp_str,
115122
help="Select errors and warnings. (comma-separated)")
116123

124+
def parse_linters(csp_str):
125+
result = list()
126+
for name in split_csp_str(csp_str):
127+
linter = LINTERS.get(name)
128+
if linter:
129+
result.append((name, linter))
130+
return result
131+
117132
parser.add_argument(
118133
"--linters", "-l", default=_Default(','.join(DEFAULT_LINTERS)),
119-
type=split_csp_str,
120-
help=(
134+
type=parse_linters, help=(
121135
"Select linters. (comma-separated). Choices are %s."
122-
% ','.join(s for s in utils.__all__)
136+
% ','.join(s for s in LINTERS.keys())
123137
))
124138

125139
parser.add_argument(

pylibs/pylama/core.py

Lines changed: 14 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,7 @@
55
"""
66
import logging
77
import re
8-
9-
from . import utils
10-
11-
12-
#: A default checkers
13-
DEFAULT_LINTERS = 'pep8', 'pyflakes', 'mccabe'
8+
from .lint import LINTERS
149

1510
#: The skip pattern
1611
SKIP_PATTERN = re.compile(r'# *noqa\b', re.I).search
@@ -25,14 +20,14 @@
2520
LOGGER.addHandler(STREAM)
2621

2722

28-
def run(path, ignore=None, select=None, linters=DEFAULT_LINTERS, config=None,
29-
**meta):
23+
def run(path, ignore=None, select=None, linters=None, config=None, **meta):
3024
""" Run a code checkers with given params.
3125
3226
:return errors: list of dictionaries with error's information
3327
3428
"""
3529
errors = []
30+
linters = linters or LINTERS.items()
3631
params = dict(ignore=ignore, select=select)
3732
code = None
3833
try:
@@ -46,21 +41,24 @@ def run(path, ignore=None, select=None, linters=DEFAULT_LINTERS, config=None,
4641
if not params['lint']:
4742
return errors
4843

49-
for lint in linters:
50-
try:
51-
linter = getattr(utils, lint)
52-
except AttributeError:
53-
LOGGER.warning("Linter `%s` not found.", lint)
44+
for item in linters:
45+
46+
if not isinstance(item, tuple):
47+
item = (item, LINTERS.get(item))
48+
49+
name, linter = item
50+
51+
if not linter or not linter.allow(path):
5452
continue
5553

56-
result = linter(path, code=code, **meta)
54+
result = linter.run(path, code=code, **meta)
5755
for e in result:
5856
e['col'] = e.get('col') or 0
5957
e['lnum'] = e.get('lnum') or 0
6058
e['type'] = e.get('type') or 'E'
6159
e['text'] = "{0} [{1}]".format((e.get(
6260
'text') or '').strip()
63-
.replace("'", "\"").split('\n')[0], lint)
61+
.replace("'", "\"").split('\n')[0], name)
6462
e['filename'] = path or ''
6563
errors.append(e)
6664

@@ -71,7 +69,7 @@ def run(path, ignore=None, select=None, linters=DEFAULT_LINTERS, config=None,
7169
except SyntaxError as e:
7270
errors.append(dict(
7371
lnum=e.lineno or 0, type='E', col=e.offset or 0,
74-
text=e.args[0] + ' [%s]' % lint, filename=path or ''
72+
text=e.args[0] + ' [%s]' % name, filename=path or ''
7573
))
7674

7775
except Exception:
@@ -128,7 +126,6 @@ def filter_errors(e, select=None, ignore=None, **params):
128126
:return bool:
129127
130128
"""
131-
132129
if select:
133130
for s in select:
134131
if e['text'].startswith(s):

pylibs/pylama/lint/__init__.py

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
""" Custom module loader. """
2+
3+
4+
class Linter(object): # noqa
5+
6+
""" Abstract class for linter plugin. """
7+
8+
@staticmethod
9+
def allow(path):
10+
""" Check path is relevant for linter.
11+
12+
:return bool:
13+
14+
"""
15+
16+
return path.endswith('.py')
17+
18+
@staticmethod
19+
def run(path, **meta):
20+
""" Method 'run' should be defined. """
21+
22+
raise NotImplementedError(__doc__)
23+
24+
25+
LINTERS = dict()
26+
27+
28+
from os import listdir, path as op
29+
30+
curdir = op.dirname(__file__)
31+
for p in listdir(curdir):
32+
if p.startswith('pylama') and op.isdir(op.join(curdir, p)):
33+
name = p[len('pylama_'):]
34+
module = __import__(
35+
'pylama.lint.pylama_%s' % name, globals(), locals(), ['Linter'])
36+
LINTERS[name] = getattr(module, 'Linter')()
37+
38+
# try:
39+
# from pkg_resources import iter_entry_points
40+
41+
# for entry in iter_entry_points('pylama.linter'):
42+
# LINTERS[entry.name] = entry.load()()
43+
# except ImportError:
44+
# pass
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
""" Check complexity. """
2+
3+
from .. import Linter as BaseLinter
4+
5+
6+
class Linter(BaseLinter):
7+
8+
""" Mccabe code complexity. """
9+
10+
@staticmethod
11+
def run(path, code=None, complexity=8, **meta):
12+
""" MCCabe code checking.
13+
14+
:return list: List of errors.
15+
16+
"""
17+
from .mccabe import get_code_complexity
18+
19+
return get_code_complexity(code, complexity, filename=path) or []
File renamed without changes.
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
""" Check PEP257. """
2+
3+
from .. import Linter as BaseLinter
4+
5+
6+
class Linter(BaseLinter):
7+
8+
""" Mccabe code complexity. """
9+
10+
@staticmethod
11+
def run(path, **meta):
12+
""" PEP257 code checking.
13+
14+
:return list: List of errors.
15+
16+
"""
17+
f = open(path)
18+
from .pep257 import check_source
19+
20+
errors = []
21+
for er in check_source(f.read(), path):
22+
errors.append(dict(
23+
lnum=er.line,
24+
col=er.char,
25+
text='C0110 %s' % er.explanation.split('\n')[0].strip(),
26+
type='W',
27+
))
28+
return errors
File renamed without changes.

0 commit comments

Comments
 (0)