Skip to content

Commit d610ccd

Browse files
committed
Update pylama to version 3.3.2
1 parent 80dddfe commit d610ccd

File tree

15 files changed

+192
-108
lines changed

15 files changed

+192
-108
lines changed

pymode/__init__.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88

99
def auto():
1010
""" Fix PEP8 erorrs in current buffer. """
11-
1211
from .autopep8 import fix_file
1312

1413
class Options(object):
@@ -30,7 +29,6 @@ class Options(object):
3029

3130
def get_documentation():
3231
""" Search documentation and append to current buffer. """
33-
3432
try:
3533
from StringIO import StringIO
3634
except ImportError:

pymode/async.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
""" Python-mode async support. """
2+
23
try:
34
from Queue import Queue
45
except ImportError:

pymode/environment.py

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -17,20 +17,19 @@ class VimPymodeEnviroment(object):
1717
prefix = '[Pymode]'
1818

1919
def __init__(self):
20+
""" Init VIM environment. """
2021
self.current = vim.current
2122
self.options = dict(encoding=vim.eval('&enc'))
2223
self.options['debug'] = self.var('g:pymode_debug', True)
2324

2425
@property
2526
def curdir(self):
2627
""" Return current working directory. """
27-
2828
return self.var('getcwd()')
2929

3030
@property
3131
def curbuf(self):
3232
""" Return current buffer. """
33-
3433
return self.current.buffer
3534

3635
@property
@@ -45,7 +44,6 @@ def cursor(self):
4544
@property
4645
def source(self):
4746
""" Return source of current buffer. """
48-
4947
return "\n".join(self.lines)
5048

5149
@property
@@ -66,7 +64,6 @@ def var(self, name, to_bool=False):
6664
:return vimobj:
6765
6866
"""
69-
7067
value = vim.eval(name)
7168

7269
if to_bool:
@@ -82,7 +79,6 @@ def message(self, msg, history=False):
8279
:return: :None
8380
8481
"""
85-
8682
if history:
8783
return vim.command('echom "%s"' % str(msg))
8884

@@ -149,16 +145,14 @@ def error(self, msg):
149145

150146
def debug(self, msg, *args):
151147
""" Print debug information. """
152-
153148
if self.options.get('debug'):
154149
print("%s %s [%s]" % (
155150
int(time.time()), msg, ', '.join([str(a) for a in args])))
156151

157152
def stop(self, value=None):
158153
""" Break Vim function. """
159-
160154
cmd = 'return'
161-
if not value is None:
155+
if value is not None:
162156
cmd += ' ' + self.prepare_value(value)
163157
vim.command(cmd)
164158

@@ -168,7 +162,6 @@ def catch_exceptions(self, func):
168162
:return func:
169163
170164
"""
171-
172165
def _wrapper(*args, **kwargs):
173166
try:
174167
return func(*args, **kwargs)
@@ -181,7 +174,6 @@ def _wrapper(*args, **kwargs):
181174

182175
def run(self, name, *args):
183176
""" Run vim function. """
184-
185177
vim.command('call %s(%s)' % (name, ", ".join([
186178
self.prepare_value(a) for a in args
187179
])))
@@ -198,7 +190,6 @@ def prepare_value(self, value, dumps=True):
198190
:return unicode string:
199191
200192
"""
201-
202193
if dumps:
203194
value = json.dumps(value)
204195

@@ -229,12 +220,10 @@ def get_offset_params(self, cursor=None, base=""):
229220

230221
def goto_line(self, line):
231222
""" Go to line. """
232-
233223
vim.command('normal %sggzz' % line)
234224

235225
def goto_file(self, path, cmd='e', force=False):
236226
""" Function description. """
237-
238227
if force or os.path.abspath(path) != self.curbuf.name:
239228
self.debug('read', path)
240229
vim.command("%s %s" % (cmd, path))

pymode/libs/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__ = "3.2.0"
8+
__version__ = "3.3.2"
99
__project__ = "pylama"
1010
__author__ = "Kirill Klenov <horneds@gmail.com>"
1111
__license__ = "GNU LGPL"

pymode/libs/pylama/config.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,8 @@ def __init__(self, value=None):
3333
def __str__(self):
3434
return str(self.value)
3535

36-
__repr__ = lambda s: "<_Default [%s]>" % s.value
36+
def __repr__(self):
37+
return "<_Default [%s]>" % self.value
3738

3839

3940
def split_csp_str(s):

pymode/libs/pylama/core.py

Lines changed: 60 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,11 @@
66
import re
77

88
import logging
9+
from collections import defaultdict
910

1011
from .config import process_value, LOGGER
1112
from .lint.extensions import LINTERS
13+
from .errors import DUPLICATES, Error
1214

1315

1416
#: The skip pattern
@@ -20,18 +22,24 @@
2022
re.I | re.M)
2123

2224

23-
def run(path, code=None, options=None):
25+
def run(path='', code=None, options=None):
2426
""" Run a code checkers with given params.
2527
2628
:return errors: list of dictionaries with error's information
2729
2830
"""
2931
errors = []
30-
params = dict(ignore=options.ignore, select=options.select)
3132
fileconfig = dict()
32-
for mask in options.file_params:
33-
if mask.match(path):
34-
fileconfig.update(options.file_params[mask])
33+
params = dict()
34+
linters = LINTERS
35+
linter_params = dict()
36+
37+
if options:
38+
linters = options.linters
39+
linter_params = options.linter_params
40+
for mask in options.file_params:
41+
if mask.match(path):
42+
fileconfig.update(options.file_params[mask])
3543

3644
try:
3745
with CodeContext(code, path) as ctx:
@@ -41,51 +49,43 @@ def run(path, code=None, options=None):
4149
if params.get('skip'):
4250
return errors
4351

44-
for item in options.linters:
52+
for item in linters:
4553

4654
if not isinstance(item, tuple):
4755
item = (item, LINTERS.get(item))
4856

49-
name, linter = item
57+
lname, linter = item
5058

51-
if not linter or not linter.allow(path):
59+
if not linter or path and not linter.allow(path):
5260
continue
5361

54-
LOGGER.info("Run %s", name)
55-
meta = options.linter_params.get(name, dict())
56-
result = linter.run(path, code=code, **meta)
57-
for e in result:
58-
e['linter'] = name
59-
e['col'] = e.get('col') or 0
60-
e['lnum'] = e.get('lnum') or 0
61-
e['type'] = e.get('type') or 'E'
62-
e['text'] = "%s [%s]" % (
63-
e.get('text', '').strip().split('\n')[0], name)
64-
e['filename'] = path or ''
65-
errors.append(e)
62+
LOGGER.info("Run %s", lname)
63+
meta = linter_params.get(lname, dict())
64+
errors += [Error(filename=path, linter=lname, **e)
65+
for e in linter.run(path, code=code, **meta)]
6666

6767
except IOError as e:
6868
LOGGER.debug("IOError %s", e)
69-
errors.append(dict(
70-
lnum=0, type='E', col=0, text=str(e), filename=path or ''))
69+
errors.append(Error(text=str(e), filename=path, linter=lname))
7170

7271
except SyntaxError as e:
7372
LOGGER.debug("SyntaxError %s", e)
74-
errors.append(dict(
75-
lnum=e.lineno or 0, type='E', col=e.offset or 0,
76-
text=e.args[0] + ' [%s]' % name, filename=path or ''
77-
))
73+
errors.append(
74+
Error(linter=lname, lnum=e.lineno, col=e.offset, text=e.args[0],
75+
filename=path))
7876

7977
except Exception as e:
8078
import traceback
8179
LOGGER.info(traceback.format_exc())
8280

83-
errors = [er for er in errors if filter_errors(er, **params)]
81+
errors = filter_errors(errors, **params)
82+
83+
errors = list(remove_duplicates(errors))
8484

8585
if code and errors:
8686
errors = filter_skiplines(code, errors)
8787

88-
return sorted(errors, key=lambda x: x['lnum'])
88+
return sorted(errors, key=lambda e: e.lnum)
8989

9090

9191
def parse_modeline(code):
@@ -107,7 +107,10 @@ def prepare_params(modeline, fileconfig, options):
107107
:return dict:
108108
109109
"""
110-
params = dict(ignore=options.ignore, select=options.select, skip=False)
110+
params = dict(skip=False, ignore=[], select=[])
111+
if options:
112+
params['ignore'] = options.ignore
113+
params['select'] = options.select
111114

112115
for config in filter(None, [modeline, fileconfig]):
113116
for key in ('ignore', 'select'):
@@ -120,23 +123,26 @@ def prepare_params(modeline, fileconfig, options):
120123
return params
121124

122125

123-
def filter_errors(e, select=None, ignore=None, **params):
126+
def filter_errors(errors, select=None, ignore=None, **params):
124127
""" Filter a erros by select and ignore options.
125128
126129
:return bool:
127130
128131
"""
129-
if select:
130-
for s in select:
131-
if e['text'].startswith(s):
132-
return True
133-
134-
if ignore:
135-
for s in ignore:
136-
if e['text'].startswith(s):
137-
return False
132+
select = select or []
133+
ignore = ignore or []
138134

139-
return True
135+
for e in errors:
136+
for s in select:
137+
if e.number.startswith(s):
138+
yield e
139+
break
140+
else:
141+
for s in ignore:
142+
if e.number.startswith(s):
143+
break
144+
else:
145+
yield e
140146

141147

142148
def filter_skiplines(code, errors):
@@ -148,18 +154,30 @@ def filter_skiplines(code, errors):
148154
if not errors:
149155
return errors
150156

151-
enums = set(er['lnum'] for er in errors)
157+
enums = set(er.lnum for er in errors)
152158
removed = set([
153159
num for num, l in enumerate(code.split('\n'), 1)
154160
if num in enums and SKIP_PATTERN(l)
155161
])
156162

157163
if removed:
158-
errors = [er for er in errors if not er['lnum'] in removed]
164+
errors = [er for er in errors if er.lnum not in removed]
159165

160166
return errors
161167

162168

169+
def remove_duplicates(errors):
170+
""" Remove same errors from others linters. """
171+
passed = defaultdict(list)
172+
for error in errors:
173+
key = error.linter, error.number
174+
if key in DUPLICATES:
175+
if key in passed[error.lnum]:
176+
continue
177+
passed[error.lnum] = DUPLICATES[key]
178+
yield error
179+
180+
163181
class CodeContext(object):
164182

165183
""" Read file if code is None. """

pymode/libs/pylama/errors.py

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
""" Dont duplicate errors same type. """
2+
3+
DUPLICATES = (
4+
5+
# multiple statements on one line
6+
[('pep8', 'E701'), ('pylint', 'C0321')],
7+
8+
# missing whitespace around operator
9+
[('pep8', 'E225'), ('pylint', 'C0326')],
10+
11+
# unused variable
12+
[('pylint', 'W0612'), ('pyflakes', 'W0612')],
13+
14+
# undefined variable
15+
[('pylint', 'E0602'), ('pyflakes', 'E0602')],
16+
17+
# unused import
18+
[('pylint', 'W0611'), ('pyflakes', 'W0611')],
19+
20+
# unexpected spaces
21+
[('pylint', 'C0326'), ('pep8', 'E251')],
22+
23+
# long lines
24+
[('pylint', 'C0301'), ('pep8', 'E501')],
25+
26+
# whitespace before '('
27+
[('pylint', 'C0326'), ('pep8', 'E211')],
28+
29+
# statement ends with a semicolon
30+
[('pylint', 'W0301'), ('pep8', 'E703')],
31+
32+
# multiple statements on one line
33+
[('pylint', 'C0321'), ('pep8', 'E702')],
34+
35+
)
36+
37+
DUPLICATES = dict((key, values) for values in DUPLICATES for key in values)
38+
39+
40+
class Error(object):
41+
42+
""" Store error information. """
43+
44+
def __init__(self, linter="", col=1, lnum=1, type="E",
45+
text="unknown error", filename="", **kwargs):
46+
""" Init error information with default values. """
47+
text = ' '.join(str(text).strip().split('\n'))
48+
if linter:
49+
text = "%s [%s]" % (text, linter)
50+
number = text.split(' ', 1)[0]
51+
self._info = dict(linter=linter, col=col, lnum=lnum, type=type,
52+
text=text, filename=filename, number=number)
53+
54+
def __getattr__(self, name):
55+
return self._info[name]
56+
57+
def __getitem__(self, name):
58+
return self._info[name]
59+
60+
def __repr__(self):
61+
return "<Error: %s %s>" % (self.number, self.linter)
62+
63+
# pylama:ignore=W0622,D

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy