Skip to content

Commit b1beaae

Browse files
committed
Update pylama to version 1.5.0
1 parent f32a512 commit b1beaae

Some content is hidden

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

68 files changed

+2120
-1781
lines changed

Changelog.rst

+1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ Changelog
66
* Added PEP257 checker;
77
* Support 'pudb' in breakpoints;
88
* Pyrun can now operate on a range of lines, and does not need to save (c) lawrenceakka
9+
* Update pylama to version 1.5.0
910

1011
## 2013-05-15 0.6.18
1112
--------------------

pylibs/pylama/__init__.py

+5-5
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
"""
2-
Code audit tool for python.
1+
""" Code audit tool for python.
2+
3+
:copyright: 2013 by Kirill Klenov.
4+
:license: BSD, see LICENSE for more details.
35
4-
:copyright: 2013 by Kirill Klenov.
5-
:license: BSD, see LICENSE for more details.
66
"""
77

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

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

pylibs/pylama/checkers/mccabe.py

+14-16
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,18 @@
33
http://nedbatchelder.com/blog/200803/python_code_complexity_microtool.html
44
MIT License.
55
"""
6-
from __future__ import absolute_import, with_statement
6+
from __future__ import with_statement
77

8-
import sys
9-
10-
import ast
118
import optparse
12-
from ast import iter_child_nodes
9+
import sys
1310
from collections import defaultdict
11+
try:
12+
import ast
13+
from ast import iter_child_nodes
14+
except ImportError: # Python 2.5
15+
from flake8.util import ast, iter_child_nodes
1416

15-
16-
__version__ = '0.2'
17+
__version__ = '0.2.1'
1718

1819

1920
class ASTVisitor(object):
@@ -263,14 +264,13 @@ def get_code_complexity(code, threshold=7, filename='stdin'):
263264

264265
complx = []
265266
McCabeChecker.max_complexity = threshold
266-
for lineno, offset, text, _ in McCabeChecker(tree, filename).run():
267-
complx.append(dict(
268-
type=McCabeChecker._code,
269-
lnum=lineno,
270-
text=text,
271-
))
267+
for lineno, offset, text, check in McCabeChecker(tree, filename).run():
268+
complx.append('%s:%d:1: %s' % (filename, lineno, text))
272269

273-
return complx
270+
if len(complx) == 0:
271+
return 0
272+
print('\n'.join(complx))
273+
return len(complx)
274274

275275

276276
def get_module_complexity(module_path, threshold=7):
@@ -310,5 +310,3 @@ def main(argv):
310310

311311
if __name__ == '__main__':
312312
main(sys.argv[1:])
313-
314-
# lint=0

pylibs/pylama/checkers/pep257.py

+35-8
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ def your_check(class_docstring, context, is_script):
5454
Also, see examples in "Check functions" section.
5555
5656
"""
57+
__version__ = '0.2.4'
5758

5859
from curses.ascii import isascii
5960
import inspect
@@ -150,6 +151,23 @@ def rel_pos(abs_pos, source):
150151
return len(lines) + 1, abs_pos - len(''.join(lines))
151152

152153

154+
def get_summary_line_info(thedocstring):
155+
"""Get the (summary_line, line_number) tuple for the given docstring.
156+
157+
The returned 'summary_line' is the pep257 summary line and 'line_number' is
158+
the zero-based docstring line number containing the summary line, which
159+
will be either 0 (zeroth line) or 1 (first line). Any docstring checks
160+
relating to the summary line should use this method to ensure consistent
161+
treatment of the summary line.
162+
163+
"""
164+
lines = eval(thedocstring).split('\n')
165+
first_line = lines[0].strip()
166+
if len(lines) == 1 or len(first_line) > 0:
167+
return first_line, 0
168+
return lines[1].strip(), 1
169+
170+
153171
#
154172
# Parsing
155173
#
@@ -167,8 +185,11 @@ def parse_module_docstring(source):
167185

168186
def parse_docstring(source, what=''):
169187
"""Parse docstring given `def` or `class` source."""
188+
module_docstring = parse_module_docstring(source)
170189
if what.startswith('module'):
171-
return parse_module_docstring(source)
190+
return module_docstring
191+
if module_docstring:
192+
return module_docstring
172193
token_gen = tk.generate_tokens(StringIO(source).readline)
173194
try:
174195
kind = None
@@ -249,7 +270,7 @@ def parse_contexts(source, kind):
249270
if kind == 'def_docstring':
250271
return parse_functions(source) + parse_methods(source)
251272
if kind == 'docstring':
252-
return ([source] + parse_functions(source) +
273+
return ([parse_module_docstring(source)] + parse_functions(source) +
253274
parse_classes(source) + parse_methods(source))
254275

255276

@@ -378,7 +399,7 @@ def check_files(filenames):
378399

379400

380401
def parse_options():
381-
parser = OptionParser()
402+
parser = OptionParser(version=__version__)
382403
parser.add_option('-e', '--explain', action='store_true',
383404
help='show explanation of each error')
384405
parser.add_option('-r', '--range', action='store_true',
@@ -418,6 +439,7 @@ def main(options, arguments):
418439
f.close()
419440
for error in sorted(errors):
420441
print_error(str(error))
442+
return 1 if errors else 0
421443

422444

423445
#
@@ -546,7 +568,10 @@ def check_ends_with_period(docstring, context, is_script):
546568
The [first line of a] docstring is a phrase ending in a period.
547569
548570
"""
549-
if docstring and not eval(docstring).split('\n')[0].strip().endswith('.'):
571+
if not docstring:
572+
return
573+
(summary_line, line_number) = get_summary_line_info(docstring)
574+
if not summary_line.endswith('.'):
550575
return True
551576

552577

@@ -610,8 +635,10 @@ def check_blank_after_summary(docstring, context, is_script):
610635
if not docstring:
611636
return
612637
lines = eval(docstring).split('\n')
613-
if len(lines) > 1 and lines[1].strip() != '':
614-
return True
638+
if len(lines) > 1:
639+
(summary_line, line_number) = get_summary_line_info(docstring)
640+
if len(lines) <= (line_number+1) or lines[line_number+1].strip() != '':
641+
return True
615642

616643

617644
def check_indent(docstring, context, is_script):
@@ -645,7 +672,7 @@ def check_blank_before_after_class(class_docstring, context, is_script):
645672
"""
646673
if not class_docstring:
647674
return
648-
before, after = context.split(class_docstring)
675+
before, after = context.split(class_docstring)[:2]
649676
before_blanks = [not line.strip() for line in before.split('\n')]
650677
after_blanks = [not line.strip() for line in after.split('\n')]
651678
if before_blanks[-3:] != [False, True, True]:
@@ -671,6 +698,6 @@ def check_blank_after_last_paragraph(docstring, context, is_script):
671698

672699
if __name__ == '__main__':
673700
try:
674-
main(*parse_options())
701+
sys.exit(main(*parse_options()))
675702
except KeyboardInterrupt:
676703
pass

pylibs/pylama/checkers/pep8.py

+4-1
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@
4545
700 statements
4646
900 syntax error
4747
"""
48-
__version__ = '1.4.6'
48+
__version__ = '1.4.7a0'
4949

5050
import os
5151
import sys
@@ -1678,6 +1678,9 @@ def ignore_code(self, code):
16781678
return False. Else, if 'options.ignore' contains a prefix of
16791679
the error code, return True.
16801680
"""
1681+
if len(code) < 4 and any(s.startswith(code)
1682+
for s in self.options.select):
1683+
return False
16811684
return (code.startswith(self.options.ignore) and
16821685
not code.startswith(self.options.select))
16831686

pylibs/pylama/checkers/pylint/__init__.py

+2-3
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717

1818
def run_pylint():
1919
"""run pylint"""
20-
from .lint import Run
20+
from pylint.lint import Run
2121
Run(sys.argv[1:])
2222

2323
def run_pylint_gui():
@@ -40,6 +40,5 @@ def run_pyreverse():
4040

4141
def run_symilar():
4242
"""run symilar"""
43-
from .checkers.similar import Run
43+
from pylint.checkers.similar import Run
4444
Run(sys.argv[1:])
45-

pylibs/pylama/checkers/pylint/__pkginfo__.py

+3-2
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,10 @@
1818

1919
modname = distname = 'pylint'
2020

21-
numversion = (0, 28, 0)
21+
numversion = (1, 0, 0)
2222
version = '.'.join([str(num) for num in numversion])
2323

24-
install_requires = ['logilab-common >= 0.53.0', 'logilab-astng >= 0.24.3']
24+
install_requires = ['logilab-common >= 0.53.0', 'astroid >= 0.24.3']
2525

2626
license = 'GPL'
2727
description = "python code static checker"
@@ -66,3 +66,4 @@
6666
for filename in ('pylint', 'pylint-gui', "symilar", "epylint",
6767
"pyreverse")]
6868

69+
include_dirs = ['test']
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
# copyright 2003-2013 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
2+
# contact http://www.logilab.fr/ -- mailto:[email protected]
3+
#
4+
# This file is part of astroid.
5+
#
6+
# astroid is free software: you can redistribute it and/or modify it
7+
# under the terms of the GNU Lesser General Public License as published by the
8+
# Free Software Foundation, either version 2.1 of the License, or (at your
9+
# option) any later version.
10+
#
11+
# astroid is distributed in the hope that it will be useful, but
12+
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
14+
# for more details.
15+
#
16+
# You should have received a copy of the GNU Lesser General Public License along
17+
# with astroid. If not, see <http://www.gnu.org/licenses/>.
18+
"""Python Abstract Syntax Tree New Generation
19+
20+
The aim of this module is to provide a common base representation of
21+
python source code for projects such as pychecker, pyreverse,
22+
pylint... Well, actually the development of this library is essentially
23+
governed by pylint's needs.
24+
25+
It extends class defined in the python's _ast module with some
26+
additional methods and attributes. Instance attributes are added by a
27+
builder object, which can either generate extended ast (let's call
28+
them astroid ;) by visiting an existent ast tree or by inspecting living
29+
object. Methods are added by monkey patching ast classes.
30+
31+
Main modules are:
32+
33+
* nodes and scoped_nodes for more information about methods and
34+
attributes added to different node classes
35+
36+
* the manager contains a high level object to get astroid trees from
37+
source files and living objects. It maintains a cache of previously
38+
constructed tree for quick access
39+
40+
* builder contains the class responsible to build astroid trees
41+
"""
42+
__doctype__ = "restructuredtext en"
43+
44+
import sys
45+
import re
46+
from operator import attrgetter
47+
48+
# WARNING: internal imports order matters !
49+
50+
# make all exception classes accessible from astroid package
51+
from .exceptions import *
52+
53+
# make all node classes accessible from astroid package
54+
from .nodes import *
55+
56+
# trigger extra monkey-patching
57+
from . import inference
58+
59+
# more stuff available
60+
from . import raw_building
61+
from .bases import YES, Instance, BoundMethod, UnboundMethod
62+
from .node_classes import are_exclusive, unpack_infer
63+
from .scoped_nodes import builtin_lookup
64+
65+
# make a manager instance (borg) as well as Project and Package classes
66+
# accessible from astroid package
67+
from .manager import AstroidManager, Project
68+
MANAGER = AstroidManager()
69+
del AstroidManager
70+
71+
# transform utilities (filters and decorator)
72+
73+
class AsStringRegexpPredicate(object):
74+
"""Class to be used as predicate that may be given to `register_transform`
75+
76+
First argument is a regular expression that will be searched against the `as_string`
77+
representation of the node onto which it's applied.
78+
79+
If specified, the second argument is an `attrgetter` expression that will be
80+
applied on the node first to get the actual node on which `as_string` should
81+
be called.
82+
"""
83+
def __init__(self, regexp, expression=None):
84+
self.regexp = re.compile(regexp)
85+
self.expression = expression
86+
87+
def __call__(self, node):
88+
if self.expression is not None:
89+
node = attrgetter(self.expression)(node)
90+
return self.regexp.search(node.as_string())
91+
92+
def inference_tip(infer_function):
93+
"""Given an instance specific inference function, return a function to be
94+
given to MANAGER.register_transform to set this inference function.
95+
96+
Typical usage
97+
98+
.. sourcecode:: python
99+
100+
MANAGER.register_transform(CallFunc, inference_tip(infer_named_tuple),
101+
AsStringRegexpPredicate('namedtuple', 'func'))
102+
"""
103+
def transform(node, infer_function=infer_function):
104+
node._explicit_inference = infer_function
105+
return node
106+
return transform
107+
108+
# load brain plugins
109+
# from os import listdir
110+
# from os.path import join, dirname
111+
# BRAIN_MODULES_DIR = join(dirname(__file__), 'brain')
112+
# if BRAIN_MODULES_DIR not in sys.path:
113+
# # add it to the end of the list so user path take precedence
114+
# sys.path.append(BRAIN_MODULES_DIR)
115+
# load modules in this directory
116+
# for module in listdir(BRAIN_MODULES_DIR):
117+
# if module.endswith('.py'):
118+
# __import__(module[:-3])

0 commit comments

Comments
 (0)