From 8fd36ba15b2673d0d9a230da88c7353013e44574 Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Mon, 19 Aug 2019 15:58:34 -0700 Subject: [PATCH] Put plugin options into separate argparse groups --- src/flake8/options/manager.py | 17 +++++++++++++++-- src/flake8/plugins/manager.py | 3 ++- tests/unit/test_option_manager.py | 11 +++++++++++ tests/unit/test_plugin.py | 3 ++- 4 files changed, 30 insertions(+), 4 deletions(-) diff --git a/src/flake8/options/manager.py b/src/flake8/options/manager.py index 219e0ad..9dd9128 100644 --- a/src/flake8/options/manager.py +++ b/src/flake8/options/manager.py @@ -1,9 +1,10 @@ """Option handling and Option management logic.""" import argparse import collections +import contextlib import functools import logging -from typing import Any, Dict, List, Optional, Set +from typing import Any, Dict, Generator, List, Optional, Set, Union from flake8 import utils @@ -312,7 +313,9 @@ class OptionManager(object): :param str usage: Basic usage string used by the OptionParser. """ - self.parser = argparse.ArgumentParser(prog=prog, usage=usage) + self.parser = argparse.ArgumentParser( + prog=prog, usage=usage + ) # type: Union[argparse.ArgumentParser, argparse._ArgumentGroup] self.version_action = self.parser.add_argument( "--version", action="version", version=version ) @@ -330,6 +333,16 @@ class OptionManager(object): """Convert a PluginVersion into a dictionary mapping name to value.""" return {attr: getattr(plugin, attr) for attr in ["name", "version"]} + @contextlib.contextmanager + def group(self, name): # type: (str) -> Generator[None, None, None] + """Attach options to an argparse group during this context.""" + group = self.parser.add_argument_group(name) + self.parser, orig_parser = group, self.parser + try: + yield + finally: + self.parser = orig_parser + def add_option(self, *args, **kwargs): """Create and register a new option. diff --git a/src/flake8/plugins/manager.py b/src/flake8/plugins/manager.py index 1554aa2..b1d00a7 100644 --- a/src/flake8/plugins/manager.py +++ b/src/flake8/plugins/manager.py @@ -213,7 +213,8 @@ class Plugin(object): self.name, optmanager, ) - add_options(optmanager) + with optmanager.group(self.plugin_name): + add_options(optmanager) if self.off_by_default: self.disable(optmanager) diff --git a/tests/unit/test_option_manager.py b/tests/unit/test_option_manager.py index ebcd9e7..d3cc728 100644 --- a/tests/unit/test_option_manager.py +++ b/tests/unit/test_option_manager.py @@ -307,3 +307,14 @@ def test_optparse_normalize_help(optmanager, capsys): out, err = capsys.readouterr() output = out + err assert 'default: bar' in output + + +def test_optmanager_group(optmanager, capsys): + """Test that group(...) causes options to be assigned to a group.""" + with optmanager.group('groupname'): + optmanager.add_option('--foo') + with pytest.raises(SystemExit): + optmanager.parse_args(['--help']) + out, err = capsys.readouterr() + output = out + err + assert '\ngroupname:\n' in output diff --git a/tests/unit/test_plugin.py b/tests/unit/test_plugin.py index cf87ea1..402eac8 100644 --- a/tests/unit/test_plugin.py +++ b/tests/unit/test_plugin.py @@ -5,6 +5,7 @@ import mock import pytest from flake8 import exceptions +from flake8.options import manager as options_manager from flake8.plugins import manager @@ -91,7 +92,7 @@ def test_register_options(): entry_point = mock.Mock(spec=['load']) plugin_obj = mock.Mock(spec_set=['name', 'version', 'add_options', 'parse_options']) - option_manager = mock.Mock(spec=['register_plugin']) + option_manager = mock.MagicMock(spec=options_manager.OptionManager) plugin = manager.Plugin('T000', entry_point) plugin._plugin = plugin_obj