[gnome-code-assistance] python: improve performance of the pep8 check
- From: Elad Alfassa <eladalfassa src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-code-assistance] python: improve performance of the pep8 check
- Date: Fri, 17 Nov 2017 21:14:08 +0000 (UTC)
commit a7326287018d3ef2bb79c8232d3daf4212c03b83
Author: Elad Alfassa <elad fedoraproject org>
Date: Fri Nov 17 21:53:10 2017 +0200
python: improve performance of the pep8 check
This patch significantly improves performance of the pep8 checks,
from ~400ms to ~30ms per run, by using pep8 directly instead of
launching a subprocess.
It also adds support for pycodestyle, which is the new name for
the pep8 tool (since 2016)
https://bugzilla.gnome.org/show_bug.cgi?id=790514
backends/python/__init__.py | 99 ++++++++++++++++++++++++++++++-------------
1 files changed, 69 insertions(+), 30 deletions(-)
---
diff --git a/backends/python/__init__.py b/backends/python/__init__.py
index 7776614..aa3c28a 100644
--- a/backends/python/__init__.py
+++ b/backends/python/__init__.py
@@ -1,6 +1,6 @@
# gnome code assistance python backend
# Copyright (C) 2013 Jesse van den Kieboom <jessevdk gnome org>
-# Copyright (C) 2014 Elad Alfassa <elad fedoraproject org>
+# Copyright (C) 2014, 2017 Elad Alfassa <elad fedoraproject org>
# Copyright (C) 2015 Igor Gnatenko <ignatenko src gnome org>
# Copyright (C) 2017 Luke Benstead <kazade gmail com>
#
@@ -19,8 +19,19 @@
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
import ast
-import subprocess
-import re
+
+try:
+ import pycodestyle
+ HAS_PYCODESTYLE = True
+except ImportError:
+ try:
+ # pep8 has been renamed to "pycodestyle". Maybe the user only has
+ # the old version installed, so let's try loading it before we give up
+ import pep8 as pycodestyle
+ HAS_PYCODESTYLE = True
+ except ImportError:
+ # No pep8 or pycodestyle installed
+ HAS_PYCODESTYLE = False
try:
from pylint import lint
@@ -120,55 +131,83 @@ class Pyflakes(object):
return reporter.diagnostics
+class PyCodeStyle(object):
+ """ PyCodeStyle / PEP8 backend """
+ def __init__(self, source, path):
+ self.source = source
+ self.path = path
+
+ def run(self):
+ class PyCodeStyleReporter(pycodestyle.BaseReport):
+ """
+ Custom reporter, nested as parent class will not have been imported
+ if pycodestyle/pep8 wasn't available
+ """
+ def __init__(self, *args):
+ super().__init__(*args)
+ self.diagnostics = []
+
+ def error(self, line_number, offset, text, check):
+ errorcode = super().error(line_number, offset, text, check)
+ if errorcode:
+ loc = types.SourceLocation(line=line_number, column=offset + 1)
+ severity = types.Diagnostic.Severity.INFO
+ self.diagnostics.append(types.Diagnostic(severity=severity,
+ locations=[loc.to_range()],
+ message=text))
+
+ style_guide = pycodestyle.StyleGuide(reporter=PyCodeStyleReporter)
+ reporter = style_guide.options.report
+ style_guide.input_file(self.path, lines=self.source.splitlines(True))
+ return reporter.diagnostics
+
+
class Service(transport.Service):
language = 'python'
def parse(self, doc, options):
doc.diagnostics = []
+ use_pylint = HAS_PYLINT and "pylint" in options and options["pylint"]
+
+ with open(doc.data_path) as f:
+ source = f.read()
+
+ if not use_pylint and not HAS_PYFLAKES:
+ # both pylint and pyflakes warn about syntax errors, so only need
+ # ast.parse() if we can't use either of them
+ try:
+ ast.parse(source, doc.path)
+ except SyntaxError as e:
+ loc = types.SourceLocation(line=e.lineno, column=e.offset)
+ severity = types.Diagnostic.Severity.ERROR
- try:
- with open(doc.data_path) as f:
- source = f.read()
-
- ast.parse(source, doc.path)
- except SyntaxError as e:
- loc = types.SourceLocation(line=e.lineno, column=e.offset)
- severity = types.Diagnostic.Severity.ERROR
-
- doc.diagnostics.append(types.Diagnostic(severity=severity, locations=[loc.to_range()],
message=e.msg))
-
- # PEP8 checks
- try:
- p = subprocess.Popen(['pep8', doc.data_path], stdout=subprocess.PIPE)
- for line in iter(p.stdout.readline, ''):
- if not line:
- break
- line = line.decode()
- result = re.search(':(\d*):(\d*): (.*)', line).groups()
- loc = types.SourceLocation(line=result[0], column=result[1])
- severity = types.Diagnostic.Severity.INFO
- doc.diagnostics.append(types.Diagnostic(severity=severity, locations=[loc.to_range()],
message=result[2]))
- except FileNotFoundError:
- # PEP8 is not installed. Do nothing.
- pass
+ doc.diagnostics.append(types.Diagnostic(severity=severity, locations=[loc.to_range()],
message=e.msg))
+
+ # Pycodestyle / PEP8 checks
+ if HAS_PYCODESTYLE or True:
+ pycodestyle_checker = PyCodeStyle(source, doc.path)
+ for diagnostic in pycodestyle_checker.run():
+ doc.diagnostics.append(diagnostic)
- if HAS_PYLINT and "pylint" in options and options["pylint"]:
+ # Pylint checks (if present and enabled)
+ if use_pylint:
pylint = PyLint(doc.data_path)
diagnostics = pylint.run()
for diag in diagnostics:
doc.diagnostics.append(diag)
+ # Pyflakes check (if present)
if HAS_PYFLAKES:
pyflakes = Pyflakes(doc.data_path)
diagnostics = pyflakes.run()
for diag in diagnostics:
doc.diagnostics.append(diag)
-
class Document(transport.Document, transport.Diagnostics):
pass
+
def run():
transport.Transport(Service, Document).run()
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]