All pastes #1797764 Raw Edit

Unnamed

public python v1 · immutable
#1797764 ·published 2010-02-15 23:22 UTC
rendered paste body
    import os    import re    import sys    from subprocess import Popen, PIPE    class LintRunner(object):        """ Base class provides common functionality to run              python code checkers. """        sane_default_ignore_codes = set([])        command = None        output_matcher = None        #flymake: ("\\(.*\\) at \\([^ \n]+\\) line \\([0-9]+\\)[,.\n]" 2 3 nil 1)        #or in non-retardate: r'(.*) at ([^ \n]) line ([0-9])[,.\n]'        output_format = "%(level)s %(error_type)s%(error_number)s:" \                        "%(description)s at %(filename)s line %(line_number)s."        def __init__(self, virtualenv=None, ignore_codes=(),                     use_sane_defaults=True):            if virtualenv:                # This is the least we can get away with (hopefully).                self.env = {'VIRTUAL_ENV': virtualenv,                            'PATH': virtualenv + '/bin:' + os.environ['PATH']}            else:                self.env = None            self.virtualenv = virtualenv            self.ignore_codes = set(ignore_codes)            self.use_sane_defaults = use_sane_defaults        @property        def operative_ignore_codes(self):            if self.use_sane_defaults:                return self.ignore_codes ^ self.sane_default_ignore_codes            else:                return self.ignore_codes        @property        def run_flags(self):            return ()        @classmethod        def fixup_data(cls, line, data):            return data        @classmethod        def process_output(cls, line):            m = cls.output_matcher.match(line)            if m:                fixed_data = dict.fromkeys(('level', 'error_type',                                            'error_number', 'description',                                            'filename', 'line_number'),                                           '')                fixed_data.update(cls.fixup_data(line, m.groupdict()))                print cls.output_format % fixed_data        def run(self, filename):            args = [self.command]            args.extend(self.run_flags)            args.append(filename)            process = Popen(args, stdout=PIPE, stderr=PIPE, env=self.env)            for line in process.stdout:                self.process_output(line)    class PylintRunner(LintRunner):        """ Run pylint, producing flymake readable output.        The raw output looks like:          render.py:49: [C0301] Line too long (82/80)          render.py:1: [C0111] Missing docstring          render.py:3: [E0611] No name 'Response' in module 'werkzeug'          render.py:32: [C0111, render] Missing docstring """        output_matcher = re.compile(            r'(?P<filename>[^:]+):'            r'(?P<line_number>\d+):'            r'\s*\[(?P<error_type>[WECR])(?P<error_number>[^,]+),'            r'\s*(?P<context>[^\]]+)\]'            r'\s*(?P<description>.*)$')        command = 'pylint'        sane_default_ignore_codes = set([            "C0103",  # Naming convention            "C0111",  # Missing Docstring            "E1002",  # Use super on old-style class            "W0232",  # No __init__            #"I0011",  # Warning locally suppressed using disable-msg            #"I0012",  # Warning locally suppressed using disable-msg            #"W0511",  # FIXME/TODO            #"W0142",  # *args or **kwargs magic.            "R0904",  # Too many public methods            "R0903",  # Too few public methods                    "R0201",  # Method could be a function            ])        @classmethod        def fixup_data(cls, line, data):            if data['error_type'].startswith('E'):                data['level'] = 'ERROR'            else:                data['level'] = 'WARNING'            return data        @property        def run_flags(self):            return ('--output-format', 'parseable',                    '--include-ids', 'y',                    '--reports', 'n',                    '--disable-msg=' + ','.join(self.operative_ignore_codes))    class PycheckerRunner(LintRunner):        """ Run pychecker, producing flymake readable output.        The raw output looks like:          render.py:49: Parameter (maptype) not used          render.py:49: Parameter (markers) not used          render.py:49: Parameter (size) not used          render.py:49: Parameter (zoom) not used """        command = 'pychecker'        output_matcher = re.compile(            r'(?P<filename>[^:]+):'            r'(?P<line_number>\d+):'            r'\s+(?P<description>.*)$')        @classmethod        def fixup_data(cls, line, data):            #XXX: doesn't seem to give the level            data['level'] = 'WARNING'            return data        @property        def run_flags(self):            return '--no-deprecated', '-0186', '--only', '-#0'    class Pep8Runner(LintRunner):        """ Run pep8.py, producing flymake readable output.        The raw output looks like:          spiders/structs.py:3:80: E501 line too long (80 characters)          spiders/structs.py:7:1: W291 trailing whitespace          spiders/structs.py:25:33: W602 deprecated form of raising exception          spiders/structs.py:51:9: E301 expected 1 blank line, found 0 """        command = 'pep8.py'        # sane_default_ignore_codes = set([        #     'RW29', 'W391',        #     'W291', 'WO232'])        output_matcher = re.compile(            r'(?P<filename>[^:]+):'            r'(?P<line_number>[^:]+):'            r'[^:]+:'            r' (?P<error_number>\w+) '            r'(?P<description>.+)$')        @classmethod        def fixup_data(cls, line, data):            if 'W' in data['error_number']:                data['level'] = 'WARNING'            else:                data['level'] = 'ERROR'            return data        @property        def run_flags(self):            return '--repeat', '--ignore=' + ','.join(self.ignore_codes)    if __name__ == '__main__':        from optparse import OptionParser        parser = OptionParser()        parser.add_option("-e", "--virtualenv",                          dest="virtualenv",                          default=None,                          help="virtualenv directory")        parser.add_option("-i", "--ignore_codes",                          dest="ignore_codes",                          default=(),                          help="error codes to ignore")        options, args = parser.parse_args()        pylint = PylintRunner(virtualenv=options.virtualenv,                              ignore_codes=options.ignore_codes)        pylint.run(args[0])        pychecker = PycheckerRunner(virtualenv=options.virtualenv,                                    ignore_codes=options.ignore_codes)        pychecker.run(args[0])        pep8 = Pep8Runner(virtualenv=options.virtualenv,                          ignore_codes=options.ignore_codes)        pep8.run(args[0])        sys.exit()