Bug 1399989 - Add python/mach to flake8 linter. r=gps

MozReview-Commit-ID: KKnBgYFwpfT

--HG--
extra : rebase_source : 4e4b3453a91970366dba0073853ad3ab62738c81
This commit is contained in:
Steve Armand 2017-09-17 22:41:17 -04:00
Родитель 57eb104b05
Коммит d11ffd18db
21 изменённых файлов: 76 добавлений и 65 удалений

Просмотреть файл

@ -23,14 +23,14 @@ class BuiltinCommands(object):
if not v.conditions or v.conditions[0].__name__ != 'REMOVED')
@Command('mach-commands', category='misc',
description='List all mach commands.')
description='List all mach commands.')
def commands(self):
print("\n".join(self.command_keys))
@Command('mach-debug-commands', category='misc',
description='Show info about available mach commands.')
description='Show info about available mach commands.')
@CommandArgument('match', metavar='MATCH', default=None, nargs='?',
help='Only display commands containing given substring.')
help='Only display commands containing given substring.')
def debug_commands(self, match=None):
import inspect
@ -50,4 +50,3 @@ class BuiltinCommands(object):
print('Class: %s' % cls.__name__)
print('Method: %s' % handler.method)
print('')

Просмотреть файл

@ -274,7 +274,6 @@ class ConfigSettings(collections.Mapping):
def __delattr__(self, k):
self.__delitem__(k)
def __init__(self):
self._config = RawConfigParser()
self._config.optionxform = str

Просмотреть файл

@ -7,7 +7,6 @@ from __future__ import absolute_import, unicode_literals
import argparse
import collections
import inspect
import os
import types
from .base import MachError
@ -185,7 +184,7 @@ def CommandProvider(cls):
if command.name not in seen_commands:
raise MachError('Command referenced by sub-command does not '
'exist: %s' % command.name)
'exist: %s' % command.name)
if command.name not in Registrar.command_handlers:
continue
@ -235,6 +234,7 @@ class Command(object):
return func
class SubCommand(object):
"""Decorator for functions or methods that provide a sub-command.
@ -264,6 +264,7 @@ class SubCommand(object):
return func
class CommandArgument(object):
"""Decorator for additional arguments to mach subcommands.
@ -343,4 +344,3 @@ def SettingsProvider(cls):
Registrar.register_settings_provider(cls)
return cls

Просмотреть файл

@ -68,7 +68,7 @@ class CommandAction(argparse.Action):
For more, read the docs in __call__.
"""
def __init__(self, option_strings, dest, required=True, default=None,
registrar=None, context=None):
registrar=None, context=None):
# A proper API would have **kwargs here. However, since we are a little
# hacky, we intentionally omit it as a way of detecting potentially
# breaking changes with argparse's implementation.
@ -76,7 +76,7 @@ class CommandAction(argparse.Action):
# In a similar vein, default is passed in but is not needed, so we drop
# it.
argparse.Action.__init__(self, option_strings, dest, required=required,
help=argparse.SUPPRESS, nargs=argparse.REMAINDER)
help=argparse.SUPPRESS, nargs=argparse.REMAINDER)
self._mach_registrar = registrar
self._context = context
@ -276,7 +276,7 @@ class CommandAction(argparse.Action):
description = handler.description
group.add_argument(command, help=description,
action='store_true')
action='store_true')
if disabled_commands and 'disabled' in r.categories:
title, description, _priority = r.categories['disabled']
@ -376,7 +376,7 @@ class CommandAction(argparse.Action):
for subcommand, subhandler in sorted(handler.subcommand_handlers.iteritems()):
group.add_argument(subcommand, help=subhandler.description,
action='store_true')
action='store_true')
if handler.docstring:
parser.description = format_docstring(handler.docstring)
@ -413,7 +413,7 @@ class CommandAction(argparse.Action):
def _suggest_command(self, command):
# Make sure we don't suggest any deprecated commands.
names = [h.name for h in self._mach_registrar.command_handlers.values()
if h.cls.__name__ != 'DeprecatedCommands']
if h.cls.__name__ != 'DeprecatedCommands']
# We first try to look for a valid command that is very similar to the given command.
suggested_commands = difflib.get_close_matches(command, names, cutoff=0.8)
# If we find more than one matching command, or no command at all,

Просмотреть файл

@ -200,15 +200,17 @@ class LoggingManager(object):
self.json_handlers.append(handler)
def add_terminal_logging(self, fh=sys.stdout, level=logging.INFO,
write_interval=False, write_times=True):
write_interval=False, write_times=True):
"""Enable logging to the terminal."""
formatter = StructuredHumanFormatter(self.start_time,
write_interval=write_interval, write_times=write_times)
write_interval=write_interval,
write_times=write_times)
if self.terminal:
formatter = StructuredTerminalFormatter(self.start_time,
write_interval=write_interval, write_times=write_times)
write_interval=write_interval,
write_times=write_times)
formatter.set_terminal(self.terminal)
handler = logging.StreamHandler(stream=fh)

Просмотреть файл

@ -38,7 +38,6 @@ from .logging import LoggingManager
from .registrar import Registrar
MACH_ERROR = r'''
The error occurred in mach itself. This is likely a bug in mach itself or a
fundamental problem with a loaded module.
@ -103,6 +102,7 @@ to implement a mach command. Please fix the error, or uninstall the module from
your system.
'''.lstrip()
class ArgumentParser(argparse.ArgumentParser):
"""Custom implementation argument parser to make things look pretty."""
@ -361,7 +361,7 @@ To see more help for a specific command, run:
print('mach interrupted by signal or user action. Stopping.')
return 1
except Exception as e:
except Exception:
# _run swallows exceptions in invoked handlers and converts them to
# a proper exit code. So, the only scenario where we should get an
# exception here is if _run itself raises. If _run raises, that's a
@ -393,8 +393,8 @@ To see more help for a specific command, run:
self.load_settings(self.settings_paths)
context = CommandContext(cwd=self.cwd,
settings=self.settings, log_manager=self.log_manager,
commands=Registrar)
settings=self.settings, log_manager=self.log_manager,
commands=Registrar)
if self.populate_context_handler:
self.populate_context_handler(context)
@ -416,12 +416,14 @@ To see more help for a specific command, run:
print(NO_COMMAND_ERROR)
return 1
except UnknownCommandError as e:
suggestion_message = SUGGESTED_COMMANDS_MESSAGE % (e.verb, ', '.join(e.suggested_commands)) if e.suggested_commands else ''
print(UNKNOWN_COMMAND_ERROR % (e.verb, e.command, suggestion_message))
suggestion_message = SUGGESTED_COMMANDS_MESSAGE % (
e.verb, ', '.join(e.suggested_commands)) if e.suggested_commands else ''
print(UNKNOWN_COMMAND_ERROR %
(e.verb, e.command, suggestion_message))
return 1
except UnrecognizedArgumentError as e:
print(UNRECOGNIZED_ARGUMENT_ERROR % (e.command,
' '.join(e.arguments)))
' '.join(e.arguments)))
return 1
# Add JSON logging to a file if requested.
@ -442,7 +444,8 @@ To see more help for a specific command, run:
# Always enable terminal logging. The log manager figures out if we are
# actually in a TTY or are a pipe and does the right thing.
self.log_manager.add_terminal_logging(level=log_level,
write_interval=args.log_interval, write_times=write_times)
write_interval=args.log_interval,
write_times=write_times)
if args.settings_file:
# Argument parsing has already happened, so settings that apply
@ -456,7 +459,8 @@ To see more help for a specific command, run:
try:
return Registrar._run_command_handler(handler, context=context,
debug_command=args.debug_command, **vars(args.command_args))
debug_command=args.debug_command,
**vars(args.command_args))
except KeyboardInterrupt as ki:
raise ki
except FailedCommandError as e:
@ -477,7 +481,7 @@ To see more help for a specific command, run:
if not len(stack):
print(COMMAND_ERROR)
self._print_exception(sys.stdout, exc_type, exc_value,
traceback.extract_tb(exc_tb))
traceback.extract_tb(exc_tb))
return 1
# Split the frames into those from the module containing the
@ -511,7 +515,7 @@ To see more help for a specific command, run:
def log(self, level, action, params, format_str):
"""Helper method to record a structured log event."""
self.logger.log(level, format_str,
extra={'action': action, 'params': params})
extra={'action': action, 'params': params})
def _print_error_header(self, argv, fh):
fh.write('Error running mach:\n\n')
@ -542,6 +546,7 @@ To see more help for a specific command, run:
paths = [paths]
valid_names = ('machrc', '.machrc')
def find_in_dir(base):
if os.path.isfile(base):
return base
@ -560,38 +565,40 @@ To see more help for a specific command, run:
"""Returns an argument parser for the command-line interface."""
parser = ArgumentParser(add_help=False,
usage='%(prog)s [global arguments] command [command arguments]')
usage='%(prog)s [global arguments] '
'command [command arguments]')
# Order is important here as it dictates the order the auto-generated
# help messages are printed.
global_group = parser.add_argument_group('Global Arguments')
global_group.add_argument('-v', '--verbose', dest='verbose',
action='store_true', default=False,
help='Print verbose output.')
action='store_true', default=False,
help='Print verbose output.')
global_group.add_argument('-l', '--log-file', dest='logfile',
metavar='FILENAME', type=argparse.FileType('ab'),
help='Filename to write log data to.')
metavar='FILENAME', type=argparse.FileType('ab'),
help='Filename to write log data to.')
global_group.add_argument('--log-interval', dest='log_interval',
action='store_true', default=False,
help='Prefix log line with interval from last message rather '
'than relative time. Note that this is NOT execution time '
'if there are parallel operations.')
action='store_true', default=False,
help='Prefix log line with interval from last message rather '
'than relative time. Note that this is NOT execution time '
'if there are parallel operations.')
suppress_log_by_default = False
if 'INSIDE_EMACS' in os.environ:
suppress_log_by_default = True
global_group.add_argument('--log-no-times', dest='log_no_times',
action='store_true', default=suppress_log_by_default,
help='Do not prefix log lines with times. By default, mach will '
'prefix each output line with the time since command start.')
action='store_true', default=suppress_log_by_default,
help='Do not prefix log lines with times. By default, '
'mach will prefix each output line with the time since '
'command start.')
global_group.add_argument('-h', '--help', dest='help',
action='store_true', default=False,
help='Show this help message.')
action='store_true', default=False,
help='Show this help message.')
global_group.add_argument('--debug-command', action='store_true',
help='Start a Python debugger when command is dispatched.')
help='Start a Python debugger when command is dispatched.')
global_group.add_argument('--settings', dest='settings_file',
metavar='FILENAME', default=None,
help='Path to settings file.')
metavar='FILENAME', default=None,
help='Path to settings file.')
for args, kwargs in self.global_arguments:
global_group.add_argument(*args, **kwargs)
@ -599,6 +606,6 @@ To see more help for a specific command, run:
# We need to be last because CommandAction swallows all remaining
# arguments and argparse parses arguments in the order they were added.
parser.add_argument('command', action=CommandAction,
registrar=Registrar, context=context)
registrar=Registrar, context=context)
return parser

Просмотреть файл

@ -51,5 +51,4 @@ class LoggingMixin(object):
'User login: {username}')
"""
self._logger.log(level, format_str,
extra={'action': action, 'params': params})
extra={'action': action, 'params': params})

Просмотреть файл

@ -41,9 +41,9 @@ class ProcessExecutionMixin(LoggingMixin):
"""Mix-in that provides process execution functionality."""
def run_process(self, args=None, cwd=None, append_env=None,
explicit_env=None, log_name=None, log_level=logging.INFO,
line_handler=None, require_unix_environment=False,
ensure_exit_code=0, ignore_children=False, pass_thru=False):
explicit_env=None, log_name=None, log_level=logging.INFO,
line_handler=None, require_unix_environment=False,
ensure_exit_code=0, ignore_children=False, pass_thru=False):
"""Runs a single process to completion.
Takes a list of arguments to run where the first item is the
@ -131,8 +131,9 @@ class ProcessExecutionMixin(LoggingMixin):
pass
else:
p = ProcessHandlerMixin(args, cwd=cwd, env=use_env,
processOutputLine=[handleLine], universal_newlines=True,
ignore_children=ignore_children)
processOutputLine=[handleLine],
universal_newlines=True,
ignore_children=ignore_children)
p.run()
p.processOutput()
status = p.wait()

Просмотреть файл

@ -29,11 +29,11 @@ class MachRegistrar(object):
if not handler.category:
raise MachError('Cannot register a mach command without a '
'category: %s' % name)
'category: %s' % name)
if handler.category not in self.categories:
raise MachError('Cannot register a command to an undefined '
'category: %s -> %s' % (name, handler.category))
'category: %s -> %s' % (name, handler.category))
self.command_handlers[name] = handler
self.commands_by_category[handler.category].add(name)

Просмотреть файл

@ -72,4 +72,3 @@ class TerminalFooter(object):
def draw(self):
raise Exception('draw() must be implemented.')

Просмотреть файл

@ -9,10 +9,10 @@ import os
import unittest
from mach.main import Mach
from mach.base import CommandContext
here = os.path.abspath(os.path.dirname(__file__))
class TestBase(unittest.TestCase):
provider_dir = os.path.join(here, 'providers')

Просмотреть файл

@ -9,14 +9,17 @@ from mach.decorators import (
Command,
)
def is_foo(cls):
"""Foo must be true"""
return cls.foo
def is_bar(cls):
"""Bar must be true"""
return cls.bar
@CommandProvider
class ConditionsProvider(object):
foo = True
@ -34,6 +37,7 @@ class ConditionsProvider(object):
def run_foobar(self):
pass
@CommandProvider
class ConditionsContextProvider(object):
def __init__(self, context):

Просмотреть файл

@ -9,6 +9,7 @@ from mach.decorators import (
Command,
)
@CommandProvider
class ConditionsProvider(object):
@Command('cmd_foo', category='testing', conditions=["invalid"])

Просмотреть файл

@ -4,8 +4,6 @@
from __future__ import unicode_literals
import time
from mach.decorators import (
CommandArgument,
CommandProvider,
@ -26,4 +24,3 @@ class TestCommandProvider(object):
@CommandArgument('--message', '-m', default='General Error')
def throw_deep(self, message):
throw2.throw_deep(message)

Просмотреть файл

@ -6,8 +6,10 @@
# exceptions that occur in mach command modules themselves and in the things
# they call.
def throw_deep(message):
return throw_real(message)
def throw_real(message):
raise Exception(message)

Просмотреть файл

@ -23,6 +23,7 @@ def _populate_context(context, key=None):
return False
raise AttributeError(key)
class TestConditions(TestBase):
"""Tests for conditionally filtering commands."""
@ -30,7 +31,6 @@ class TestConditions(TestBase):
return TestBase._run_mach(self, args, 'conditions.py',
context_handler=context_handler)
def test_conditions_pass(self):
"""Test that a command which passes its conditions is runnable."""
@ -65,7 +65,7 @@ class TestConditions(TestBase):
m = Mach(os.getcwd())
m.define_category('testing', 'Mach unittest', 'Testing for mach core', 10)
self.assertRaises(MachError, m.load_commands_from_file,
os.path.join(self.provider_dir, 'conditions_invalid.py'))
os.path.join(self.provider_dir, 'conditions_invalid.py'))
def test_help_message(self):
"""Test that commands that are not runnable do not show up in help."""

Просмотреть файл

@ -40,6 +40,7 @@ CONFIG2 = r"""
bar = value2
"""
@SettingsProvider
class Provider1(object):
config_settings = [

Просмотреть файл

@ -20,7 +20,7 @@ class TestErrorOutput(TestBase):
def test_command_error(self):
result, stdout, stderr = self._run_mach(['throw', '--message',
'Command Error'])
'Command Error'])
self.assertEqual(result, 1)
@ -28,7 +28,7 @@ class TestErrorOutput(TestBase):
def test_invoked_error(self):
result, stdout, stderr = self._run_mach(['throw_deep', '--message',
'Deep stack'])
'Deep stack'])
self.assertEqual(result, 1)

Просмотреть файл

@ -40,7 +40,7 @@ class TestStructuredHumanFormatter(unittest.TestCase):
value = 's\xe9curit\xe9'
logger.log(logging.INFO, 'Test: {utf}',
extra={'action': 'action', 'params': {'utf': value}})
extra={'action': 'action', 'params': {'utf': value}})
if __name__ == '__main__':

Просмотреть файл

@ -36,4 +36,3 @@ setup(
],
tests_require=['mock'],
)

Просмотреть файл

@ -4,6 +4,7 @@ flake8:
include:
- config/mozunit.py
- layout/tools/reftest
- python/mach
- python/mach_commands.py
- python/mozlint
- security/manager