Bug 1339178 - Add python/mach_commands.py and config/mozunit.py to flake8 linter, r?davehunt draft
authorAndrew Halberstadt <ahalberstadt@mozilla.com>
Tue, 29 Aug 2017 14:41:38 -0400
changeset 656761 7941be087d4d1251a90f84c0a7162cffa4b1799d
parent 656655 fb22415719a9d971a2646fa2d1b74e134ca00c3d
child 656762 b7d72c302cc50263eef2a3afb0d20202e69c7388
push id77303
push userahalberstadt@mozilla.com
push dateThu, 31 Aug 2017 15:57:40 +0000
reviewersdavehunt
bugs1339178
milestone57.0a1
Bug 1339178 - Add python/mach_commands.py and config/mozunit.py to flake8 linter, r?davehunt MozReview-Commit-ID: Gcsz6z8MeOi
config/mozunit.py
python/mach_commands.py
tools/lint/flake8.yml
--- a/config/mozunit.py
+++ b/config/mozunit.py
@@ -1,31 +1,31 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-from unittest import TextTestRunner as _TestRunner, TestResult as _TestResult
-import unittest
 import inspect
-from StringIO import StringIO
 import os
 import sys
+import unittest
+from StringIO import StringIO
+from unittest import TextTestRunner as _TestRunner, TestResult as _TestResult
 
 '''Helper to make python unit tests report the way that the Mozilla
 unit test infrastructure expects tests to report.
 
 Usage:
 
-import unittest
 import mozunit
 
 if __name__ == '__main__':
     mozunit.main()
 '''
 
+
 class _MozTestResult(_TestResult):
     def __init__(self, stream, descriptions):
         _TestResult.__init__(self)
         self.stream = stream
         self.descriptions = descriptions
 
     def getDescription(self, test):
         if self.descriptions:
@@ -63,17 +63,17 @@ class _MozTestResult(_TestResult):
     def addError(self, test, err):
         _TestResult.addError(self, test, err)
         self.printFail(test, err)
         self.stream.writeln("ERROR: {0}".format(self.getDescription(test)))
         self.stream.writeln(self.errors[-1][1])
 
     def addFailure(self, test, err):
         _TestResult.addFailure(self, test, err)
-        self.printFail(test,err)
+        self.printFail(test, err)
         self.stream.writeln("FAIL: {0}".format(self.getDescription(test)))
         self.stream.writeln(self.failures[-1][1])
 
     def printFail(self, test, err):
         exctype, value, tb = err
         message = value.message.splitlines()[0] if value.message else 'NO MESSAGE'
         # Skip test runner traceback levels
         while tb and self._is_relevant_tb_level(tb):
@@ -82,48 +82,52 @@ class _MozTestResult(_TestResult):
             _, ln, _ = inspect.getframeinfo(tb)[:3]
             message = 'line {0}: {1}'.format(ln, message)
         self.printStatus("TEST-UNEXPECTED-FAIL", test, message)
 
 
 class MozTestRunner(_TestRunner):
     def _makeResult(self):
         return _MozTestResult(self.stream, self.descriptions)
+
     def run(self, test):
         result = self._makeResult()
         test(result)
         return result
 
+
 class MockedFile(StringIO):
-    def __init__(self, context, filename, content = ''):
+    def __init__(self, context, filename, content=''):
         self.context = context
         self.name = filename
         StringIO.__init__(self, content)
 
     def close(self):
         self.context.files[self.name] = self.getvalue()
         StringIO.close(self)
 
     def __enter__(self):
         return self
 
     def __exit__(self, type, value, traceback):
         self.close()
 
+
 def normcase(path):
     '''
     Normalize the case of `path`.
 
     Don't use `os.path.normcase` because that also normalizes forward slashes
     to backslashes on Windows.
     '''
     if sys.platform.startswith('win'):
         return path.lower()
     return path
 
+
 class MockedOpen(object):
     '''
     Context manager diverting the open builtin such that opening files
     can open "virtual" file instances given when creating a MockedOpen.
 
     with MockedOpen({'foo': 'foo', 'bar': 'bar'}):
         f = open('foo', 'r')
 
@@ -133,22 +137,22 @@ class MockedOpen(object):
     doesn't touch the file system, while subsequently opening the file
     will return the recorded content.
 
     with MockedOpen():
         f = open('foo', 'w')
         f.write('foo')
     self.assertRaises(Exception,f.open('foo', 'r'))
     '''
-    def __init__(self, files = {}):
+    def __init__(self, files={}):
         self.files = {}
         for name, content in files.iteritems():
             self.files[normcase(os.path.abspath(name))] = content
 
-    def __call__(self, name, mode = 'r'):
+    def __call__(self, name, mode='r'):
         absname = normcase(os.path.abspath(name))
         if 'w' in mode:
             file = MockedFile(self, absname)
         elif absname in self.files:
             file = MockedFile(self, absname, self.files[absname])
         elif 'a' in mode:
             file = MockedFile(self, absname, self.open(name, 'r').read())
         else:
@@ -198,10 +202,11 @@ class MockedOpen(object):
             return True
 
         abspath = normcase(os.path.abspath(p) + os.sep)
         if any(f.startswith(abspath) for f in self.files):
             return True
 
         return self._orig_path_exists(p)
 
+
 def main(*args, **kwargs):
     unittest.main(testRunner=MozTestRunner(), *args, **kwargs)
--- a/python/mach_commands.py
+++ b/python/mach_commands.py
@@ -29,52 +29,52 @@ from mach.decorators import (
     CommandProvider,
     Command,
 )
 
 
 @CommandProvider
 class MachCommands(MachCommandBase):
     @Command('python', category='devenv',
-        description='Run Python.')
+             description='Run Python.')
     @CommandArgument('args', nargs=argparse.REMAINDER)
     def python(self, args):
         # Avoid logging the command
         self.log_manager.terminal_handler.setLevel(logging.CRITICAL)
 
         self._activate_virtualenv()
 
         return self.run_process([self.virtualenv_manager.python_path] + args,
-            pass_thru=True,  # Allow user to run Python interactively.
-            ensure_exit_code=False,  # Don't throw on non-zero exit code.
-            # Note: subprocess requires native strings in os.environ on Windows
-            append_env={b'PYTHONDONTWRITEBYTECODE': str('1')})
+                                pass_thru=True,  # Allow user to run Python interactively.
+                                ensure_exit_code=False,  # Don't throw on non-zero exit code.
+                                # Note: subprocess requires native strings in os.environ on Windows
+                                append_env={b'PYTHONDONTWRITEBYTECODE': str('1')})
 
     @Command('python-test', category='testing',
-        description='Run Python unit tests with an appropriate test runner.')
+             description='Run Python unit tests with an appropriate test runner.')
     @CommandArgument('--verbose',
-        default=False,
-        action='store_true',
-        help='Verbose output.')
+                     default=False,
+                     action='store_true',
+                     help='Verbose output.')
     @CommandArgument('--stop',
-        default=False,
-        action='store_true',
-        help='Stop running tests after the first error or failure.')
+                     default=False,
+                     action='store_true',
+                     help='Stop running tests after the first error or failure.')
     @CommandArgument('-j', '--jobs',
-        default=1,
-        type=int,
-        help='Number of concurrent jobs to run. Default is 1.')
+                     default=1,
+                     type=int,
+                     help='Number of concurrent jobs to run. Default is 1.')
     @CommandArgument('--subsuite',
-        default=None,
-        help=('Python subsuite to run. If not specified, all subsuites are run. '
-             'Use the string `default` to only run tests without a subsuite.'))
+                     default=None,
+                     help=('Python subsuite to run. If not specified, all subsuites are run. '
+                           'Use the string `default` to only run tests without a subsuite.'))
     @CommandArgument('tests', nargs='*',
-        metavar='TEST',
-        help=('Tests to run. Each test can be a single file or a directory. '
-              'Default test resolution relies on PYTHON_UNITTEST_MANIFESTS.'))
+                     metavar='TEST',
+                     help=('Tests to run. Each test can be a single file or a directory. '
+                           'Default test resolution relies on PYTHON_UNITTEST_MANIFESTS.'))
     def python_test(self, *args, **kwargs):
         try:
             tempdir = os.environ[b'PYTHON_TEST_TMP'] = str(tempfile.mkdtemp(suffix='-python-test'))
             return self.run_python_tests(*args, **kwargs)
         finally:
             import mozfile
             mozfile.remove(tempdir)
 
@@ -94,18 +94,18 @@ class MachCommands(MachCommandBase):
                 if t.endswith('.py') and os.path.isfile(t):
                     files.append(t)
                 elif os.path.isdir(t):
                     for root, _, _ in os.walk(t):
                         files += glob.glob(mozpath.join(root, 'test*.py'))
                         files += glob.glob(mozpath.join(root, 'unit*.py'))
                 else:
                     self.log(logging.WARN, 'python-test',
-                                 {'test': t},
-                                 'TEST-UNEXPECTED-FAIL | Invalid test: {test}')
+                             {'test': t},
+                             'TEST-UNEXPECTED-FAIL | Invalid test: {test}')
                     if stop:
                         break
             return files
 
         # Python's unittest, and in particular discover, has problems with
         # clashing namespaces when importing multiple test modules. What follows
         # is a simple way to keep environments separate, at the price of
         # launching Python multiple times. Most tests are run via mozunit,
--- a/tools/lint/flake8.yml
+++ b/tools/lint/flake8.yml
@@ -1,13 +1,15 @@
 ---
 flake8:
     description: Python linter
     include:
+        - config/mozunit.py
         - layout/tools/reftest
+        - python/mach_commands.py
         - python/mozlint
         - security/manager
         - taskcluster
         - testing/firefox-ui
         - testing/mach_commands.py
         - testing/marionette/client
         - testing/marionette/harness
         - testing/marionette/puppeteer