[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
[tor-commits] [arm/master] Checking pep8 as part of our tests
commit a9e1a21545a4016f865f2c97014db6e9e6ae9206
Author: Damian Johnson <atagar@xxxxxxxxxxxxxx>
Date: Wed Jan 1 13:08:20 2014 -0800
Checking pep8 as part of our tests
This presently blacklists all of the files we haven't rewritten yet (which is
most of them). Pep8 works on a directory level so unfortunately we need to skip
after the actual check (so this still adds a substantial bit to our test
runtime).
---
run_tests.py | 152 ++++++++++++++++++++++++++++++++++++++++++++---------
test/settings.cfg | 47 +++++++++++++++++
2 files changed, 173 insertions(+), 26 deletions(-)
diff --git a/run_tests.py b/run_tests.py
index 0135708..3ed5e25 100755
--- a/run_tests.py
+++ b/run_tests.py
@@ -18,6 +18,7 @@ from arm.util import load_settings
CONFIG = stem.util.conf.config_dict("test", {
"pep8.ignore": [],
+ "pep8.blacklist": [],
"pyflakes.ignore": [],
})
@@ -29,6 +30,41 @@ SRC_PATHS = [os.path.join(ARM_BASE, path) for path in (
)]
+def main():
+ load_settings()
+
+ test_config = stem.util.conf.get_config("test")
+ test_config.load(os.path.join(ARM_BASE, "test", "settings.cfg"))
+
+ clean_orphaned_pyc()
+
+ tests = unittest.defaultTestLoader.discover('test', pattern='*.py')
+ test_runner = unittest.TextTestRunner()
+ test_runner.run(tests)
+
+ print
+
+ static_check_issues = {}
+
+ if stem.util.system.is_available("pyflakes"):
+ static_check_issues.update(get_pyflakes_issues(SRC_PATHS))
+
+ if stem.util.system.is_available("pep8"):
+ static_check_issues.update(get_stylistic_issues(SRC_PATHS))
+
+ if static_check_issues:
+ print "STATIC CHECKS"
+
+ for file_path in static_check_issues:
+ print "* %s" % file_path
+
+ for line_number, msg in static_check_issues[file_path]:
+ line_count = "%-4s" % line_number
+ print " line %s - %s" % (line_count, msg)
+
+ print
+
+
def clean_orphaned_pyc():
for root, _, files in os.walk(os.path.dirname(__file__)):
for filename in files:
@@ -43,6 +79,80 @@ def clean_orphaned_pyc():
os.remove(pyc_path)
+def get_stylistic_issues(paths):
+ """
+ Checks for stylistic issues that are an issue according to the parts of PEP8
+ we conform to. This alsochecks a few other stylistic issues:
+
+ * two space indentations
+ * tabs are the root of all evil and should be shot on sight
+ * standard newlines (\\n), not windows (\\r\\n) nor classic mac (\\r)
+ * checks that we're using 'as' for exceptions rather than a comma
+
+ :param list paths: paths to search for stylistic issues
+
+ :returns: **dict** of the form ``path => [(line_number, message)...]``
+ """
+
+ ignored_issues = ','.join(CONFIG["pep8.ignore"])
+ issues = {}
+
+ for path in paths:
+ pep8_output = stem.util.system.call(
+ "pep8 --ignore %s %s" % (ignored_issues, path),
+ ignore_exit_status = True,
+ )
+
+ for line in pep8_output:
+ line_match = re.match("^(.*):(\d+):(\d+): (.*)$", line)
+
+ if line_match:
+ path, line, _, issue = line_match.groups()
+
+ if path in CONFIG["pep8.blacklist"]:
+ continue
+
+ issues.setdefault(path, []).append((int(line), issue))
+
+ for file_path in _get_files_with_suffix(path):
+ if file_path in CONFIG["pep8.blacklist"]:
+ continue
+
+ with open(file_path) as f:
+ file_contents = f.read()
+
+ lines, file_issues, prev_indent = file_contents.split("\n"), [], 0
+ is_block_comment = False
+
+ for index, line in enumerate(lines):
+ whitespace, content = re.match("^(\s*)(.*)$", line).groups()
+
+ if '"""' in content:
+ is_block_comment = not is_block_comment
+
+ if "\t" in whitespace:
+ file_issues.append((index + 1, "indentation has a tab"))
+ elif "\r" in content:
+ file_issues.append((index + 1, "contains a windows newline"))
+ elif content != content.rstrip():
+ file_issues.append((index + 1, "line has trailing whitespace"))
+ elif content.lstrip().startswith("except") and content.endswith(", exc:"):
+ # Python 2.6 - 2.7 supports two forms for exceptions...
+ #
+ # except ValueError, exc:
+ # except ValueError as exc:
+ #
+ # The former is the old method and no longer supported in python 3
+ # going forward.
+
+ file_issues.append((index + 1, "except clause should use 'as', not comma"))
+
+ if file_issues:
+ issues[file_path] = file_issues
+
+ return issues
+
+
def get_pyflakes_issues(paths):
"""
Performs static checks via pyflakes.
@@ -97,36 +207,26 @@ def get_pyflakes_issues(paths):
return issues
-def main():
- load_settings()
-
- test_config = stem.util.conf.get_config("test")
- test_config.load(os.path.join(ARM_BASE, "test", "settings.cfg"))
-
- clean_orphaned_pyc()
-
- tests = unittest.defaultTestLoader.discover('test', pattern='*.py')
- test_runner = unittest.TextTestRunner()
- test_runner.run(tests)
-
- print
-
- static_check_issues = {}
-
- if stem.util.system.is_available("pyflakes"):
- static_check_issues.update(get_pyflakes_issues(SRC_PATHS))
+def _get_files_with_suffix(base_path, suffix = ".py"):
+ """
+ Iterates over files in a given directory, providing filenames with a certain
+ suffix.
- if static_check_issues:
- print "STATIC CHECKS"
+ :param str base_path: directory to be iterated over
+ :param str suffix: filename suffix to look for
- for file_path in static_check_issues:
- print "* %s" % file_path
+ :returns: iterator that yields the absolute path for files with the given suffix
+ """
- for line_number, msg in static_check_issues[file_path]:
- line_count = "%-4s" % line_number
- print " line %s - %s" % (line_count, msg)
+ if os.path.isfile(base_path):
+ if base_path.endswith(suffix):
+ yield base_path
+ else:
+ for root, _, files in os.walk(base_path):
+ for filename in files:
+ if filename.endswith(suffix):
+ yield os.path.join(root, filename)
- print
if __name__ == '__main__':
main()
diff --git a/test/settings.cfg b/test/settings.cfg
index cf0049c..169a016 100644
--- a/test/settings.cfg
+++ b/test/settings.cfg
@@ -1,3 +1,50 @@
+# PEP8 compliance issues that we're ignoreing.
+
+pep8.ignore E111
+pep8.ignore E121
+pep8.ignore E501
+pep8.ignore E251
+pep8.ignore E127
+
+# Files we haven't gotten around to revisiing yet. This list will be going away
+# completely before our next release.
+
+pep8.blacklist ./arm/connections/__init__.py
+pep8.blacklist ./arm/connections/circEntry.py
+pep8.blacklist ./arm/connections/connEntry.py
+pep8.blacklist ./arm/connections/connPanel.py
+pep8.blacklist ./arm/connections/countPopup.py
+pep8.blacklist ./arm/connections/descriptorPopup.py
+pep8.blacklist ./arm/connections/entries.py
+
+pep8.blacklist ./arm/graphing/__init__.py
+pep8.blacklist ./arm/graphing/bandwidthStats.py
+pep8.blacklist ./arm/graphing/connStats.py
+pep8.blacklist ./arm/graphing/graphPanel.py
+pep8.blacklist ./arm/graphing/resourceStats.py
+
+pep8.blacklist ./arm/menu/__init__.py
+pep8.blacklist ./arm/menu/actions.py
+pep8.blacklist ./arm/menu/item.py
+pep8.blacklist ./arm/menu/menu.py
+
+pep8.blacklist ./arm/util/connections.py
+pep8.blacklist ./arm/util/panel.py
+pep8.blacklist ./arm/util/sysTools.py
+pep8.blacklist ./arm/util/textInput.py
+pep8.blacklist ./arm/util/torConfig.py
+pep8.blacklist ./arm/util/torTools.py
+pep8.blacklist ./arm/util/uiTools.py
+
+pep8.blacklist ./arm/__init__.py
+pep8.blacklist ./arm/configPanel.py
+pep8.blacklist ./arm/controller.py
+pep8.blacklist ./arm/headerPanel.py
+pep8.blacklist ./arm/logPanel.py
+pep8.blacklist ./arm/popups.py
+pep8.blacklist ./arm/prereq.py
+pep8.blacklist ./arm/torrcPanel.py
+
# False positives from pyflakes. These are mappings between the path and the
# issue.
_______________________________________________
tor-commits mailing list
tor-commits@xxxxxxxxxxxxxxxxxxxx
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits