summaryrefslogtreecommitdiff
path: root/Tools/Scripts/webkitpy/style/checkers/python.py
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@digia.com>2012-11-22 09:09:45 +0100
committerSimon Hausmann <simon.hausmann@digia.com>2012-11-22 09:10:13 +0100
commit470286ecfe79d59df14944e5b5d34630fc739391 (patch)
tree43983212872e06cebefd2ae474418fa2908ca54c /Tools/Scripts/webkitpy/style/checkers/python.py
parent23037105e948c2065da5a937d3a2396b0ff45c1e (diff)
downloadqtwebkit-470286ecfe79d59df14944e5b5d34630fc739391.tar.gz
Imported WebKit commit e89504fa9195b2063b2530961d4b73dd08de3242 (http://svn.webkit.org/repository/webkit/trunk@135485)
Change-Id: I03774e5ac79721c13ffa30d152537a74d0b12e66 Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
Diffstat (limited to 'Tools/Scripts/webkitpy/style/checkers/python.py')
-rw-r--r--Tools/Scripts/webkitpy/style/checkers/python.py82
1 files changed, 77 insertions, 5 deletions
diff --git a/Tools/Scripts/webkitpy/style/checkers/python.py b/Tools/Scripts/webkitpy/style/checkers/python.py
index 8cfd1b2d3..9fc436f3d 100644
--- a/Tools/Scripts/webkitpy/style/checkers/python.py
+++ b/Tools/Scripts/webkitpy/style/checkers/python.py
@@ -22,23 +22,32 @@
"""Supports checking WebKit style in Python files."""
+import re
+from StringIO import StringIO
+
+from webkitpy.common.system.filesystem import FileSystem
+from webkitpy.common.webkit_finder import WebKitFinder
from webkitpy.thirdparty.autoinstalled import pep8
+from webkitpy.thirdparty.autoinstalled.pylint import lint
+from webkitpy.thirdparty.autoinstalled.pylint.reporters.text import ParseableTextReporter
class PythonChecker(object):
-
"""Processes text lines for checking style."""
-
def __init__(self, file_path, handle_style_error):
self._file_path = file_path
self._handle_style_error = handle_style_error
def check(self, lines):
+ self._check_pep8(lines)
+ self._check_pylint(lines)
+
+ def _check_pep8(self, lines):
# Initialize pep8.options, which is necessary for
# Checker.check_all() to execute.
pep8.process_options(arglist=[self._file_path])
- checker = pep8.Checker(self._file_path)
+ pep8_checker = pep8.Checker(self._file_path)
def _pep8_handle_error(line_number, offset, text, check):
# FIXME: Incorporate the character offset into the error output.
@@ -51,6 +60,69 @@ class PythonChecker(object):
self._handle_style_error(line_number, category, 5, pep8_message)
- checker.report_error = _pep8_handle_error
+ pep8_checker.report_error = _pep8_handle_error
+ pep8_errors = pep8_checker.check_all()
+
+ def _check_pylint(self, lines):
+ pylinter = Pylinter()
+
+ # FIXME: for now, we only report pylint errors, but we should be catching and
+ # filtering warnings using the rules in style/checker.py instead.
+ output = pylinter.run(['-E', self._file_path])
+
+ lint_regex = re.compile('([^:]+):([^:]+): \[([^]]+)\] (.*)')
+ for error in output.getvalue().splitlines():
+ match_obj = lint_regex.match(error)
+ assert(match_obj)
+ line_number = int(match_obj.group(2))
+ category_and_method = match_obj.group(3).split(', ')
+ category = 'pylint/' + (category_and_method[0])
+ if len(category_and_method) > 1:
+ message = '[%s] %s' % (category_and_method[1], match_obj.group(4))
+ else:
+ message = match_obj.group(4)
+ self._handle_style_error(line_number, category, 5, message)
+
+
+class Pylinter(object):
+ # We filter out these messages because they are bugs in pylint that produce false positives.
+ # FIXME: Does it make sense to combine these rules with the rules in style/checker.py somehow?
+ FALSE_POSITIVES = [
+ # possibly http://www.logilab.org/ticket/98613 ?
+ "Instance of 'Popen' has no 'poll' member",
+ "Instance of 'Popen' has no 'returncode' member",
+ "Instance of 'Popen' has no 'stdin' member",
+ "Instance of 'Popen' has no 'stdout' member",
+ "Instance of 'Popen' has no 'stderr' member",
+ "Instance of 'Popen' has no 'wait' member",
+ ]
+
+ def __init__(self):
+ self._pylintrc = WebKitFinder(FileSystem()).path_from_webkit_base('Tools', 'Scripts', 'webkitpy', 'pylintrc')
+
+ def run(self, argv):
+ output = _FilteredStringIO(self.FALSE_POSITIVES)
+ lint.Run(['--rcfile', self._pylintrc] + argv, reporter=ParseableTextReporter(output=output), exit=False)
+ return output
+
+
+class _FilteredStringIO(StringIO):
+ def __init__(self, bad_messages):
+ StringIO.__init__(self)
+ self.dropped_last_msg = False
+ self.bad_messages = bad_messages
+
+ def write(self, msg=''):
+ if not self._filter(msg):
+ StringIO.write(self, msg)
- errors = checker.check_all()
+ def _filter(self, msg):
+ if any(bad_message in msg for bad_message in self.bad_messages):
+ self.dropped_last_msg = True
+ return True
+ if self.dropped_last_msg:
+ # We drop the newline after a dropped message as well.
+ self.dropped_last_msg = False
+ if msg == '\n':
+ return True
+ return False