[tor-commits] [stem/master] Renaming check_whitespace.py to static_checks.py

atagar at torproject.org atagar at torproject.org
Mon Feb 4 04:46:07 UTC 2013


commit d44018a5566fe5c92a326a413768bdd8462c425e
Author: Damian Johnson <atagar at torproject.org>
Date:   Sun Feb 3 20:01:35 2013 -0800

    Renaming check_whitespace.py to static_checks.py
    
    The check_whitespace.py module no longer... well, checks whitespace. Rather, it
    has become a dumping ground for all of the static checks that we do. Renaming
    it to something more appropriate.
---
 run_tests.py             |   22 ++--
 test/__init__.py         |    2 +-
 test/check_whitespace.py |  229 ----------------------------------------------
 test/static_checks.py    |  229 ++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 241 insertions(+), 241 deletions(-)

diff --git a/run_tests.py b/run_tests.py
index feab3a7..1154870 100755
--- a/run_tests.py
+++ b/run_tests.py
@@ -19,9 +19,9 @@ import stem.util.enum
 
 from stem.util import log, system, term
 
-import test.check_whitespace
 import test.output
 import test.runner
+import test.static_checks
 import test.unit.connection.authentication
 import test.unit.control.controller
 import test.unit.descriptor.export
@@ -276,7 +276,7 @@ def _clean_orphaned_pyc():
   orphaned_pyc = []
 
   for base_dir in ('stem', 'test', 'run_tests.py'):
-    for pyc_path in test.check_whitespace._get_files_with_suffix(base_dir, ".pyc"):
+    for pyc_path in test.static_checks._get_files_with_suffix(base_dir, ".pyc"):
       # If we're running python 3 then the *.pyc files are no longer bundled
       # with the *.py. Rather, they're in a __pycache__ directory.
       #
@@ -350,9 +350,9 @@ def _python3_setup(python3_destination):
 
 def _print_style_issues():
   base_path = os.path.sep.join(__file__.split(os.path.sep)[:-1]).lstrip("./")
-  style_issues = test.check_whitespace.get_issues(os.path.join(base_path, "stem"))
-  style_issues.update(test.check_whitespace.get_issues(os.path.join(base_path, "test")))
-  style_issues.update(test.check_whitespace.get_issues(os.path.join(base_path, "run_tests.py")))
+  style_issues = test.static_checks.get_issues(os.path.join(base_path, "stem"))
+  style_issues.update(test.static_checks.get_issues(os.path.join(base_path, "test")))
+  style_issues.update(test.static_checks.get_issues(os.path.join(base_path, "run_tests.py")))
 
   # If we're doing some sort of testing (unit or integ) and pyflakes is
   # available then use it. Its static checks are pretty quick so there's not
@@ -360,17 +360,17 @@ def _print_style_issues():
 
   if CONFIG["argument.unit"] or CONFIG["argument.integ"]:
     if system.is_available("pyflakes"):
-      style_issues.update(test.check_whitespace.pyflakes_issues(os.path.join(base_path, "stem")))
-      style_issues.update(test.check_whitespace.pyflakes_issues(os.path.join(base_path, "test")))
-      style_issues.update(test.check_whitespace.pyflakes_issues(os.path.join(base_path, "run_tests.py")))
+      style_issues.update(test.static_checks.pyflakes_issues(os.path.join(base_path, "stem")))
+      style_issues.update(test.static_checks.pyflakes_issues(os.path.join(base_path, "test")))
+      style_issues.update(test.static_checks.pyflakes_issues(os.path.join(base_path, "run_tests.py")))
     else:
       test.output.print_line("Static error checking requires pyflakes. Please install it from ...\n  http://pypi.python.org/pypi/pyflakes\n", *ERROR_ATTR)
 
   if CONFIG["argument.style"]:
     if system.is_available("pep8"):
-      style_issues.update(test.check_whitespace.pep8_issues(os.path.join(base_path, "stem")))
-      style_issues.update(test.check_whitespace.pep8_issues(os.path.join(base_path, "test")))
-      style_issues.update(test.check_whitespace.pep8_issues(os.path.join(base_path, "run_tests.py")))
+      style_issues.update(test.static_checks.pep8_issues(os.path.join(base_path, "stem")))
+      style_issues.update(test.static_checks.pep8_issues(os.path.join(base_path, "test")))
+      style_issues.update(test.static_checks.pep8_issues(os.path.join(base_path, "run_tests.py")))
     else:
       test.output.print_line("Style checks require pep8. Please install it from...\n  http://pypi.python.org/pypi/pep8\n", *ERROR_ATTR)
 
diff --git a/test/__init__.py b/test/__init__.py
index 43fdd7f..098ce65 100644
--- a/test/__init__.py
+++ b/test/__init__.py
@@ -3,12 +3,12 @@ Unit and integration tests for the stem library.
 """
 
 __all__ = [
-  "check_whitespace",
   "mocking",
   "network",
   "output",
   "prompt",
   "runner",
+  "static_checks",
   "tutorial",
   "utils",
 ]
diff --git a/test/check_whitespace.py b/test/check_whitespace.py
deleted file mode 100644
index 2f758b8..0000000
--- a/test/check_whitespace.py
+++ /dev/null
@@ -1,229 +0,0 @@
-"""
-Performs a check that our python source code follows its whitespace conventions
-which are...
-
-* 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)
-
-This also checks for 2.5 compatibility issues (yea, they're not whitespace but
-it's so much easier to do here...):
-
-* checks that anything using the 'with' keyword has...
-  from __future__ import with_statement
-"""
-
-from __future__ import with_statement
-
-import re
-import os
-
-from stem.util import conf, system
-
-# if ran directly then run over everything one level up
-DEFAULT_TARGET = os.path.sep.join(__file__.split(os.path.sep)[:-1])
-
-# mapping of files to the issues that should be ignored
-PYFLAKES_IGNORE = None
-
-CONFIG = conf.config_dict("test", {
-  "pyflakes.ignore": [],
-  "integ.test_directory": "./test/data",
-})
-
-
-def pep8_issues(base_path = DEFAULT_TARGET):
-  """
-  Checks for stylistic issues that are an issue according to the parts of PEP8
-  we conform to.
-
-  :param str base_path: directory to be iterated over
-
-  :returns: dict of the form ``path => [(line_number, message)...]``
-  """
-
-  # The pep8 command give output of the form...
-  #
-  #   FILE:LINE:CHARACTER ISSUE
-  #
-  # ... for instance...
-  #
-  #   ./test/mocking.py:868:31: E225 missing whitespace around operator
-  #
-  # Ignoring the following compliance issues.
-  #
-  # * E251 no spaces around keyword / parameter equals
-  #
-  #   This one I dislike a great deal. It makes keyword arguments different
-  #   from assignments which looks... aweful. I'm not sure what PEP8's author
-  #   was on when he wrote this one but it's stupid.
-  #
-  #   Someone else can change this if they really care.
-  #
-  # * E501 line is over 79 characters
-  #
-  #   We're no longer on TTY terminals. Overly constraining line length makes
-  #   things far less readable, encouraging bad practices like abbreviated
-  #   variable names.
-  #
-  #   If the code fits on my tiny netbook screen then it's narrow enough.
-  #
-  # * E111 and E121 four space indentations
-  #
-  #   Ahhh, indentation. The holy war that'll never die. Sticking with two
-  #   space indentations since it leads to shorter lines.
-  #
-  # * E127 continuation line over-indented for visual indent
-  #
-  #   Pep8 only works with this one if we have four space indents (its
-  #   detection is based on multiples of four).
-
-  ignored_issues = "E111,E121,E501,E251,E127"
-
-  issues = {}
-  pep8_output = system.call("pep8 --ignore %s %s" % (ignored_issues, base_path))
-
-  for line in pep8_output:
-    line_match = re.match("^(.*):(\d+):(\d+): (.*)$", line)
-
-    if line_match:
-      path, line, _, issue = line_match.groups()
-
-      if not _is_test_data(path):
-        issues.setdefault(path, []).append((int(line), issue))
-
-  return issues
-
-
-def pyflakes_issues(base_path = DEFAULT_TARGET):
-  """
-  Checks for issues via pyflakes. False positives can be whitelisted via our
-  test configuration.
-
-  :param str base_path: directory to be iterated over
-
-  :returns: dict of the form ``path => [(line_number, message)...]``
-  """
-
-  global PYFLAKES_IGNORE
-
-  if PYFLAKES_IGNORE is None:
-    pyflakes_ignore = {}
-
-    for line in CONFIG["pyflakes.ignore"]:
-      path, issue = line.split("=>")
-      pyflakes_ignore.setdefault(path.strip(), []).append(issue.strip())
-
-    PYFLAKES_IGNORE = pyflakes_ignore
-
-  # Pyflakes issues are of the form...
-  #
-  #   FILE:LINE: ISSUE
-  #
-  # ... for instance...
-  #
-  #   stem/prereq.py:73: 'long_to_bytes' imported but unused
-  #   stem/control.py:957: undefined name 'entry'
-
-  issues = {}
-  pyflakes_output = system.call("pyflakes %s" % base_path)
-
-  for line in pyflakes_output:
-    line_match = re.match("^(.*):(\d+): (.*)$", line)
-
-    if line_match:
-      path, line, issue = line_match.groups()
-
-      if not _is_test_data(path) and not issue in PYFLAKES_IGNORE.get(path, []):
-        issues.setdefault(path, []).append((int(line), issue))
-
-  return issues
-
-
-def get_issues(base_path = DEFAULT_TARGET):
-  """
-  Checks python source code in the given directory for whitespace issues.
-
-  :param str base_path: directory to be iterated over
-
-  :returns: dict of the form ``path => [(line_number, message)...]``
-  """
-
-  # TODO: This does not check that block indentations are two spaces because
-  # differentiating source from string blocks ("""foo""") is more of a pita
-  # than I want to deal with right now.
-
-  issues = {}
-
-  for file_path in _get_files_with_suffix(base_path):
-    if _is_test_data(file_path):
-      continue
-
-    with open(file_path) as f:
-      file_contents = f.read()
-
-    lines, file_issues, prev_indent = file_contents.split("\n"), [], 0
-    has_with_import, given_with_warning = False, False
-    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 content == "from __future__ import with_statement":
-        has_with_import = True
-      elif content.startswith("with ") and content.endswith(":") \
-        and not has_with_import and not given_with_warning and not is_block_comment:
-        file_issues.append((index + 1, "missing 'with' import (from __future__ import with_statement)"))
-        given_with_warning = True
-
-      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"))
-
-    if file_issues:
-      issues[file_path] = file_issues
-
-  return issues
-
-
-def _is_test_data(path):
-  return os.path.normpath(path).startswith(os.path.normpath(CONFIG["integ.test_directory"]))
-
-
-def _get_files_with_suffix(base_path, suffix = ".py"):
-  """
-  Iterates over files in a given directory, providing filenames with a certain
-  suffix.
-
-  :param str base_path: directory to be iterated over
-  :param str suffix: filename suffix to look for
-
-  :returns: iterator that yields the absolute path for files with the given suffix
-  """
-
-  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)
-
-if __name__ == '__main__':
-  issues = get_issues()
-
-  for file_path in issues:
-    print file_path
-
-    for line_number, msg in issues[file_path]:
-      line_count = "%-4s" % line_number
-      print "  line %s %s" % (line_count, msg)
-
-    print
diff --git a/test/static_checks.py b/test/static_checks.py
new file mode 100644
index 0000000..2f758b8
--- /dev/null
+++ b/test/static_checks.py
@@ -0,0 +1,229 @@
+"""
+Performs a check that our python source code follows its whitespace conventions
+which are...
+
+* 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)
+
+This also checks for 2.5 compatibility issues (yea, they're not whitespace but
+it's so much easier to do here...):
+
+* checks that anything using the 'with' keyword has...
+  from __future__ import with_statement
+"""
+
+from __future__ import with_statement
+
+import re
+import os
+
+from stem.util import conf, system
+
+# if ran directly then run over everything one level up
+DEFAULT_TARGET = os.path.sep.join(__file__.split(os.path.sep)[:-1])
+
+# mapping of files to the issues that should be ignored
+PYFLAKES_IGNORE = None
+
+CONFIG = conf.config_dict("test", {
+  "pyflakes.ignore": [],
+  "integ.test_directory": "./test/data",
+})
+
+
+def pep8_issues(base_path = DEFAULT_TARGET):
+  """
+  Checks for stylistic issues that are an issue according to the parts of PEP8
+  we conform to.
+
+  :param str base_path: directory to be iterated over
+
+  :returns: dict of the form ``path => [(line_number, message)...]``
+  """
+
+  # The pep8 command give output of the form...
+  #
+  #   FILE:LINE:CHARACTER ISSUE
+  #
+  # ... for instance...
+  #
+  #   ./test/mocking.py:868:31: E225 missing whitespace around operator
+  #
+  # Ignoring the following compliance issues.
+  #
+  # * E251 no spaces around keyword / parameter equals
+  #
+  #   This one I dislike a great deal. It makes keyword arguments different
+  #   from assignments which looks... aweful. I'm not sure what PEP8's author
+  #   was on when he wrote this one but it's stupid.
+  #
+  #   Someone else can change this if they really care.
+  #
+  # * E501 line is over 79 characters
+  #
+  #   We're no longer on TTY terminals. Overly constraining line length makes
+  #   things far less readable, encouraging bad practices like abbreviated
+  #   variable names.
+  #
+  #   If the code fits on my tiny netbook screen then it's narrow enough.
+  #
+  # * E111 and E121 four space indentations
+  #
+  #   Ahhh, indentation. The holy war that'll never die. Sticking with two
+  #   space indentations since it leads to shorter lines.
+  #
+  # * E127 continuation line over-indented for visual indent
+  #
+  #   Pep8 only works with this one if we have four space indents (its
+  #   detection is based on multiples of four).
+
+  ignored_issues = "E111,E121,E501,E251,E127"
+
+  issues = {}
+  pep8_output = system.call("pep8 --ignore %s %s" % (ignored_issues, base_path))
+
+  for line in pep8_output:
+    line_match = re.match("^(.*):(\d+):(\d+): (.*)$", line)
+
+    if line_match:
+      path, line, _, issue = line_match.groups()
+
+      if not _is_test_data(path):
+        issues.setdefault(path, []).append((int(line), issue))
+
+  return issues
+
+
+def pyflakes_issues(base_path = DEFAULT_TARGET):
+  """
+  Checks for issues via pyflakes. False positives can be whitelisted via our
+  test configuration.
+
+  :param str base_path: directory to be iterated over
+
+  :returns: dict of the form ``path => [(line_number, message)...]``
+  """
+
+  global PYFLAKES_IGNORE
+
+  if PYFLAKES_IGNORE is None:
+    pyflakes_ignore = {}
+
+    for line in CONFIG["pyflakes.ignore"]:
+      path, issue = line.split("=>")
+      pyflakes_ignore.setdefault(path.strip(), []).append(issue.strip())
+
+    PYFLAKES_IGNORE = pyflakes_ignore
+
+  # Pyflakes issues are of the form...
+  #
+  #   FILE:LINE: ISSUE
+  #
+  # ... for instance...
+  #
+  #   stem/prereq.py:73: 'long_to_bytes' imported but unused
+  #   stem/control.py:957: undefined name 'entry'
+
+  issues = {}
+  pyflakes_output = system.call("pyflakes %s" % base_path)
+
+  for line in pyflakes_output:
+    line_match = re.match("^(.*):(\d+): (.*)$", line)
+
+    if line_match:
+      path, line, issue = line_match.groups()
+
+      if not _is_test_data(path) and not issue in PYFLAKES_IGNORE.get(path, []):
+        issues.setdefault(path, []).append((int(line), issue))
+
+  return issues
+
+
+def get_issues(base_path = DEFAULT_TARGET):
+  """
+  Checks python source code in the given directory for whitespace issues.
+
+  :param str base_path: directory to be iterated over
+
+  :returns: dict of the form ``path => [(line_number, message)...]``
+  """
+
+  # TODO: This does not check that block indentations are two spaces because
+  # differentiating source from string blocks ("""foo""") is more of a pita
+  # than I want to deal with right now.
+
+  issues = {}
+
+  for file_path in _get_files_with_suffix(base_path):
+    if _is_test_data(file_path):
+      continue
+
+    with open(file_path) as f:
+      file_contents = f.read()
+
+    lines, file_issues, prev_indent = file_contents.split("\n"), [], 0
+    has_with_import, given_with_warning = False, False
+    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 content == "from __future__ import with_statement":
+        has_with_import = True
+      elif content.startswith("with ") and content.endswith(":") \
+        and not has_with_import and not given_with_warning and not is_block_comment:
+        file_issues.append((index + 1, "missing 'with' import (from __future__ import with_statement)"))
+        given_with_warning = True
+
+      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"))
+
+    if file_issues:
+      issues[file_path] = file_issues
+
+  return issues
+
+
+def _is_test_data(path):
+  return os.path.normpath(path).startswith(os.path.normpath(CONFIG["integ.test_directory"]))
+
+
+def _get_files_with_suffix(base_path, suffix = ".py"):
+  """
+  Iterates over files in a given directory, providing filenames with a certain
+  suffix.
+
+  :param str base_path: directory to be iterated over
+  :param str suffix: filename suffix to look for
+
+  :returns: iterator that yields the absolute path for files with the given suffix
+  """
+
+  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)
+
+if __name__ == '__main__':
+  issues = get_issues()
+
+  for file_path in issues:
+    print file_path
+
+    for line_number, msg in issues[file_path]:
+      line_count = "%-4s" % line_number
+      print "  line %s %s" % (line_count, msg)
+
+    print





More information about the tor-commits mailing list