1212default_linters = 'pep8' , 'pyflakes' , 'mccabe'
1313default_complexity = 10
1414logger = logging .Logger ('pylama' )
15+ stream = logging .StreamHandler ()
16+ logger .addHandler (stream )
1517
1618SKIP_PATTERN = '# nolint'
1719
@@ -29,38 +31,40 @@ def run(path, ignore=None, select=None, linters=default_linters, **meta): # nol
2931 continue
3032
3133 try :
32- code = open (path , "rU" ).read () + '\n \n '
33- params = parse_modeline (code )
34- params ['skip' ] = [False ]
35- for line in code .split ('\n ' ):
36- params ['skip' ].append (line .endswith (SKIP_PATTERN ))
37-
38- if params .get ('lint_ignore' ):
39- ignore += params .get ('lint_ignore' ).split (',' )
40-
41- if params .get ('lint_select' ):
42- select += params .get ('lint_select' ).split (',' )
43-
44- if params .get ('lint' ):
45- for e in linter (path , code = code , ** meta ):
46- e ['col' ] = e .get ('col' ) or 0
47- e ['lnum' ] = e .get ('lnum' ) or 0
48- e ['type' ] = e .get ('type' ) or 'W'
49- e ['text' ] = "{0} [{1}]" .format ((e .get (
50- 'text' ) or '' ).strip ()
51- .replace ("'" , "\" " ).split ('\n ' )[0 ], lint )
52- e ['filename' ] = path or ''
53- if not params ['skip' ][e ['lnum' ]]:
54- errors .append (e )
55-
56- except IOError , e :
34+ with open (path , "rU" ) as f :
35+ code = f .read () + '\n \n '
36+ params = parse_modeline (code )
37+ params ['skip' ] = [False ]
38+ for line in code .split ('\n ' ):
39+ params ['skip' ].append (line .endswith (SKIP_PATTERN ))
40+
41+ if params .get ('lint_ignore' ):
42+ ignore += params .get ('lint_ignore' ).split (',' )
43+
44+ if params .get ('lint_select' ):
45+ select += params .get ('lint_select' ).split (',' )
46+
47+ if params .get ('lint' ):
48+ result = linter (path , code = code , ** meta )
49+ for e in result :
50+ e ['col' ] = e .get ('col' ) or 0
51+ e ['lnum' ] = e .get ('lnum' ) or 0
52+ e ['type' ] = e .get ('type' ) or 'E'
53+ e ['text' ] = "{0} [{1}]" .format ((e .get (
54+ 'text' ) or '' ).strip ()
55+ .replace ("'" , "\" " ).split ('\n ' )[0 ], lint )
56+ e ['filename' ] = path or ''
57+ if not params ['skip' ][e ['lnum' ]]:
58+ errors .append (e )
59+
60+ except IOError as e :
5761 errors .append (dict (
5862 lnum = 0 ,
5963 type = 'E' ,
6064 col = 0 ,
6165 text = str (e )
6266 ))
63- except SyntaxError , e :
67+ except SyntaxError as e :
6468 errors .append (dict (
6569 lnum = e .lineno or 0 ,
6670 type = 'E' ,
@@ -69,7 +73,7 @@ def run(path, ignore=None, select=None, linters=default_linters, **meta): # nol
6973 ))
7074 break
7175
72- except Exception , e :
76+ except Exception as e :
7377 import traceback
7478 logging .error (traceback .format_exc ())
7579
@@ -96,6 +100,9 @@ def shell():
96100
97101 split_csp_list = lambda s : list (set (i for i in s .split (',' ) if i ))
98102
103+ parser .add_argument (
104+ "--format" , "-f" , default = 'pep8' , choices = ['pep8' , 'pylint' ],
105+ help = "Error format." )
99106 parser .add_argument (
100107 "--select" , "-s" , default = '' ,
101108 type = split_csp_list ,
@@ -116,14 +123,19 @@ def shell():
116123 parser .add_argument ("--complexity" , "-c" , default = default_complexity ,
117124 type = int , help = "Set mccabe complexity." )
118125 parser .add_argument ("--report" , "-r" , help = "Filename for report." )
126+ parser .add_argument ("--hook" , action = "store_true" ,
127+ help = "Install Git (Mercurial) hook." )
119128 args = parser .parse_args ()
120129
121130 # Setup logger
122131 logger .setLevel (logging .INFO if args .verbose else logging .WARN )
123132 if args .report :
133+ logger .removeHandler (stream )
124134 logger .addHandler (logging .FileHandler (args .report , mode = 'w' ))
125- else :
126- logger .addHandler (logging .StreamHandler ())
135+
136+ if args .hook :
137+ from .hook import install_hook
138+ return install_hook (args .path )
127139
128140 paths = [args .path ]
129141
@@ -132,16 +144,37 @@ def shell():
132144 for root , _ , files in walk (args .path ):
133145 paths += [op .join (root , f ) for f in files if f .endswith ('.py' )]
134146
135- for path in skip_paths (args , paths ):
147+ check_files (
148+ paths ,
149+ rootpath = args .path ,
150+ skip = args .skip ,
151+ frmt = args .format ,
152+ ignore = args .ignore ,
153+ select = args .select ,
154+ linters = args .linters ,
155+ complexity = args .complexity ,
156+ )
157+
158+
159+ def check_files (paths , rootpath = None , skip = None , frmt = "pep8" ,
160+ select = None , ignore = None , linters = default_linters ,
161+ complexity = default_complexity ):
162+ rootpath = rootpath or getcwd ()
163+ pattern = "%(rel)s:%(lnum)s:%(col)s: %(text)s"
164+ if frmt == 'pylint' :
165+ pattern = "%(rel)s:%(lnum)s: [%(type)s] %(text)s"
166+
167+ errors = []
168+ for path in skip_paths (skip , paths ):
136169 logger .info ("Parse file: %s" % path )
137- errors = run (path , ignore = args . ignore , select = args . select ,
138- linters = args . linters , complexity = args . complexity )
170+ errors = run (path , ignore = ignore , select = select ,
171+ linters = linters , complexity = complexity )
139172 for error in errors :
140173 try :
141174 error ['rel' ] = op .relpath (
142- error ['filename' ], op .dirname (args . path ))
175+ error ['filename' ], op .dirname (rootpath ))
143176 error ['col' ] = error .get ('col' , 1 )
144- logger .warning ("%(rel)s:%(lnum)s:%(col)s: %(text)s" , error )
177+ logger .warning (pattern , error )
145178 except KeyError :
146179 continue
147180
@@ -152,9 +185,9 @@ def shell():
152185 r'^\s*#\s+(?:pymode\:)?((?:lint[\w_]*=[^:\n\s]+:?)+)' , re .I | re .M )
153186
154187
155- def skip_paths (args , paths ):
188+ def skip_paths (skip , paths ):
156189 for path in paths :
157- if args . skip and any (pattern .match (path ) for pattern in args . skip ):
190+ if skip and any (pattern .match (path ) for pattern in skip ):
158191 continue
159192 yield path
160193
0 commit comments