Bug 1339178 - Add python/mach_commands.py and config/mozunit.py to flake8 linter, r?davehunt
MozReview-Commit-ID: Gcsz6z8MeOi
--- 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