55"""
66import logging
77import re
8- from .lint import LINTERS
8+ from .lint . extensions import LINTERS
99
1010#: The skip pattern
1111SKIP_PATTERN = re .compile (r'# *noqa\b' , re .I ).search
2020LOGGER .addHandler (STREAM )
2121
2222
23- def run (path , ignore = None , select = None , linters = None , config = None , ** meta ):
23+ def run (
24+ path , ignore = None , select = None , linters = None , config = None , code = None ,
25+ ** meta ):
2426 """ Run a code checkers with given params.
2527
2628 :return errors: list of dictionaries with error's information
@@ -29,11 +31,9 @@ def run(path, ignore=None, select=None, linters=None, config=None, **meta):
2931 errors = []
3032 linters = linters or LINTERS .items ()
3133 params = dict (ignore = ignore , select = select )
32- code = None
3334 try :
34- with open (path , 'rU' ) as f :
35- code = f .read () + '\n \n '
36-
35+ with CodeContext (code , path ) as ctx :
36+ code = ctx .code
3737 params = prepare_params (
3838 parse_modeline (code ), config , ignore = ignore , select = select
3939 )
@@ -78,7 +78,7 @@ def run(path, ignore=None, select=None, linters=None, config=None, **meta):
7878
7979 errors = [er for er in errors if filter_errors (er , ** params )]
8080
81- if code :
81+ if code and errors :
8282 errors = filter_skiplines (code , errors )
8383
8484 return sorted (errors , key = lambda x : x ['lnum' ])
@@ -158,3 +158,23 @@ def filter_skiplines(code, errors):
158158 errors = [er for er in errors if not er ['lnum' ] in removed ]
159159
160160 return errors
161+
162+
163+ class CodeContext (object ):
164+
165+ """ Read file if code is None. """
166+
167+ def __init__ (self , code , path ):
168+ self .code = code
169+ self .path = path
170+ self ._file = None
171+
172+ def __enter__ (self ):
173+ if self .code is None :
174+ self ._file = open (self .path , 'rU' )
175+ self .code = self ._file .read () + '\n \n '
176+ return self
177+
178+ def __exit__ (self ):
179+ if not self ._file is None :
180+ self ._file .close ()
0 commit comments