Part of Slepp's ProjectsPastebinTURLImagebinFilebin
Feedback -- English French German Japanese
Create Upload Newest Tools Donate
Sign In | Create Account

Paste Description for Unnamed

This is a script which runs and parses the output of various
Python code checking programs to work with flymake.

Unnamed
Monday, February 15th, 2010 at 11:25:45pm UTC 

  1.     import os
  2.     import re
  3.     import sys
  4.  
  5.     from subprocess import Popen, PIPE
  6.  
  7.  
  8.     class LintRunner(object):
  9.         """ Base class provides common functionality to run
  10.               python code checkers. """
  11.  
  12.         sane_default_ignore_codes = set([])
  13.         command = None
  14.         output_matcher = None
  15.  
  16.         #flymake: ("\\(.*\\) at \\([^ \n]+\\) line \\([0-9]+\\)[,.\n]" 2 3 nil 1)
  17.         #or in non-retardate: r'(.*) at ([^ \n]) line ([0-9])[,.\n]'
  18.         output_format = "%(level)s %(error_type)s%(error_number)s:" \
  19.                         "%(description)s at %(filename)s line %(line_number)s."
  20.  
  21.         def __init__(self, virtualenv=None, ignore_codes=(),
  22.                      use_sane_defaults=True):
  23.             if virtualenv:
  24.                 # This is the least we can get away with (hopefully).
  25.                 self.env = {'VIRTUAL_ENV': virtualenv,
  26.                             'PATH': virtualenv + '/bin:' + os.environ['PATH']}
  27.             else:
  28.                 self.env = None
  29.  
  30.             self.virtualenv = virtualenv
  31.             self.ignore_codes = set(ignore_codes)
  32.             self.use_sane_defaults = use_sane_defaults
  33.  
  34.         @property
  35.         def operative_ignore_codes(self):
  36.             if self.use_sane_defaults:
  37.                 return self.ignore_codes ^ self.sane_default_ignore_codes
  38.             else:
  39.                 return self.ignore_codes
  40.  
  41.         @property
  42.         def run_flags(self):
  43.             return ()
  44.  
  45.         @classmethod
  46.         def fixup_data(cls, line, data):
  47.             return data
  48.  
  49.         @classmethod
  50.         def process_output(cls, line):
  51.             m = cls.output_matcher.match(line)
  52.             if m:
  53.                 fixed_data = dict.fromkeys(('level', 'error_type',
  54.                                             'error_number', 'description',
  55.                                             'filename', 'line_number'),
  56.                                            '')
  57.                 fixed_data.update(cls.fixup_data(line, m.groupdict()))
  58.                 print cls.output_format % fixed_data
  59.  
  60.         def run(self, filename):
  61.             args = [self.command]
  62.             args.extend(self.run_flags)
  63.             args.append(filename)
  64.  
  65.             process = Popen(args, stdout=PIPE, stderr=PIPE, env=self.env)
  66.  
  67.             for line in process.stdout:
  68.                 self.process_output(line)
  69.  
  70.  
  71.     class PylintRunner(LintRunner):
  72.         """ Run pylint, producing flymake readable output.
  73.  
  74.         The raw output looks like:
  75.           render.py:49: [C0301] Line too long (82/80)
  76.           render.py:1: [C0111] Missing docstring
  77.           render.py:3: [E0611] No name 'Response' in module 'werkzeug'
  78.           render.py:32: [C0111, render] Missing docstring """
  79.  
  80.         output_matcher = re.compile(
  81.             r'(?P<filename>[^:]+):'
  82.             r'(?P<line_number>\d+):'
  83.             r'\s*\[(?P<error_type>[WECR])(?P<error_number>[^,]+),'
  84.             r'\s*(?P<context>[^\]]+)\]'
  85.             r'\s*(?P<description>.*)$')
  86.  
  87.         command = 'pylint'
  88.         sane_default_ignore_codes = set([
  89.             "C0103"# Naming convention
  90.             "C0111"# Missing Docstring
  91.             "E1002"# Use super on old-style class
  92.             "W0232"# No __init__
  93.             #"I0011",  # Warning locally suppressed using disable-msg
  94.             #"I0012",  # Warning locally suppressed using disable-msg
  95.             #"W0511",  # FIXME/TODO
  96.             #"W0142",  # *args or **kwargs magic.
  97.             "R0904"# Too many public methods
  98.             "R0903"# Too few public methods       
  99.             "R0201"# Method could be a function
  100.             ])
  101.  
  102.         @classmethod
  103.         def fixup_data(cls, line, data):
  104.             if data['error_type'].startswith('E'):
  105.                 data['level'] = 'ERROR'
  106.             else:
  107.                 data['level'] = 'WARNING'
  108.             return data
  109.  
  110.         @property
  111.         def run_flags(self):
  112.             return ('--output-format', 'parseable',
  113.                     '--include-ids', 'y',
  114.                     '--reports', 'n',
  115.                     '--disable-msg=' + ','.join(self.operative_ignore_codes))
  116.  
  117.  
  118.     class PycheckerRunner(LintRunner):
  119.         """ Run pychecker, producing flymake readable output.
  120.  
  121.         The raw output looks like:
  122.           render.py:49: Parameter (maptype) not used
  123.           render.py:49: Parameter (markers) not used
  124.           render.py:49: Parameter (size) not used
  125.           render.py:49: Parameter (zoom) not used """
  126.  
  127.         command = 'pychecker'
  128.  
  129.         output_matcher = re.compile(
  130.             r'(?P<filename>[^:]+):'
  131.             r'(?P<line_number>\d+):'
  132.             r'\s+(?P<description>.*)$')
  133.  
  134.         @classmethod
  135.         def fixup_data(cls, line, data):
  136.             #XXX: doesn't seem to give the level
  137.             data['level'] = 'WARNING'
  138.             return data
  139.  
  140.         @property
  141.         def run_flags(self):
  142.             return '--no-deprecated', '-0186', '--only', '-#0'
  143.  
  144.  
  145.     class Pep8Runner(LintRunner):
  146.         """ Run pep8.py, producing flymake readable output.
  147.  
  148.         The raw output looks like:
  149.           spiders/structs.py:3:80: E501 line too long (80 characters)
  150.           spiders/structs.py:7:1: W291 trailing whitespace
  151.           spiders/structs.py:25:33: W602 deprecated form of raising exception
  152.           spiders/structs.py:51:9: E301 expected 1 blank line, found 0 """
  153.  
  154.         command = 'pep8.py'
  155.         # sane_default_ignore_codes = set([
  156.         #     'RW29', 'W391',
  157.         #     'W291', 'WO232'])
  158.  
  159.         output_matcher = re.compile(
  160.             r'(?P<filename>[^:]+):'
  161.             r'(?P<line_number>[^:]+):'
  162.             r'[^:]+:'
  163.             r' (?P<error_number>\w+) '
  164.             r'(?P<description>.+)$')
  165.  
  166.         @classmethod
  167.         def fixup_data(cls, line, data):
  168.             if 'W' in data['error_number']:
  169.                 data['level'] = 'WARNING'
  170.             else:
  171.                 data['level'] = 'ERROR'
  172.  
  173.             return data
  174.  
  175.         @property
  176.         def run_flags(self):
  177.             return '--repeat', '--ignore=' + ','.join(self.ignore_codes)
  178.  
  179.  
  180.     if __name__ == '__main__':
  181.         from optparse import OptionParser
  182.         parser = OptionParser()
  183.         parser.add_option("-e", "--virtualenv",
  184.                           dest="virtualenv",
  185.                           default=None,
  186.                           help="virtualenv directory")
  187.         parser.add_option("-i", "--ignore_codes",
  188.                           dest="ignore_codes",
  189.                           default=(),
  190.                           help="error codes to ignore")
  191.         options, args = parser.parse_args()
  192.  
  193.         pylint = PylintRunner(virtualenv=options.virtualenv,
  194.                               ignore_codes=options.ignore_codes)
  195.         pylint.run(args[0])
  196.  
  197.         pychecker = PycheckerRunner(virtualenv=options.virtualenv,
  198.                                     ignore_codes=options.ignore_codes)
  199.         pychecker.run(args[0])
  200.  
  201.         pep8 = Pep8Runner(virtualenv=options.virtualenv,
  202.                           ignore_codes=options.ignore_codes)
  203.         pep8.run(args[0])
  204.         sys.exit()

Update the Post

Either update this post and resubmit it with changes, or make a new post.

You may also comment on this post.

update paste below
details of the post (optional)

Note: Only the paste content is required, though the following information can be useful to others.

Save name / title?

(space separated, optional)



Please note that information posted here will expire by default in one month. If you do not want it to expire, please set the expiry time above. If it is set to expire, web search engines will not be allowed to index it prior to it expiring. Items that are not marked to expire will be indexable by search engines. Be careful with your passwords. All illegal activities will be reported and any information will be handed over to the authorities, so be good.

comments powered by Disqus
worth-right