mirror of
https://github.com/PyCQA/flake8.git
synced 2026-04-11 15:24:18 +00:00
Merge branch 'type_annotate_option_manager' into 'master'
Type annotate flake8.options.manager See merge request pycqa/flake8!352
This commit is contained in:
commit
a13f02a386
8 changed files with 142 additions and 115 deletions
|
|
@ -1,6 +1,6 @@
|
||||||
repos:
|
repos:
|
||||||
- repo: https://github.com/pre-commit/mirrors-mypy
|
- repo: https://github.com/pre-commit/mirrors-mypy
|
||||||
rev: v0.701
|
rev: v0.720
|
||||||
hooks:
|
hooks:
|
||||||
- id: mypy
|
- id: mypy
|
||||||
exclude: ^(docs/|example-plugin/|tests/fixtures)
|
exclude: ^(docs/|example-plugin/|tests/fixtures)
|
||||||
|
|
|
||||||
|
|
@ -118,6 +118,8 @@ disallow_untyped_defs = true
|
||||||
disallow_untyped_defs = true
|
disallow_untyped_defs = true
|
||||||
[mypy-flake8.formatting.*]
|
[mypy-flake8.formatting.*]
|
||||||
disallow_untyped_defs = true
|
disallow_untyped_defs = true
|
||||||
|
[mypy-flake8.options.manager]
|
||||||
|
disallow_untyped_defs = true
|
||||||
[mypy-flake8.main.cli]
|
[mypy-flake8.main.cli]
|
||||||
disallow_untyped_defs = true
|
disallow_untyped_defs = true
|
||||||
[mypy-flake8.statistics]
|
[mypy-flake8.statistics]
|
||||||
|
|
|
||||||
|
|
@ -388,7 +388,7 @@ class FileChecker(object):
|
||||||
self.should_process = not self.processor.should_ignore_file()
|
self.should_process = not self.processor.should_ignore_file()
|
||||||
self.statistics["physical lines"] = len(self.processor.lines)
|
self.statistics["physical lines"] = len(self.processor.lines)
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self): # type: () -> str
|
||||||
"""Provide helpful debugging representation."""
|
"""Provide helpful debugging representation."""
|
||||||
return "FileChecker for {}".format(self.filename)
|
return "FileChecker for {}".format(self.filename)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,27 +2,53 @@
|
||||||
import argparse
|
import argparse
|
||||||
import collections
|
import collections
|
||||||
import contextlib
|
import contextlib
|
||||||
|
import enum
|
||||||
import functools
|
import functools
|
||||||
import logging
|
import logging
|
||||||
from typing import Any, Dict, Generator, List, Optional, Set, Tuple, Union
|
from typing import Any, Callable, cast, Dict, Generator, List, Mapping
|
||||||
|
from typing import Optional, Sequence, Set, Tuple, Union
|
||||||
|
|
||||||
from flake8 import utils
|
from flake8 import utils
|
||||||
|
|
||||||
|
if False: # TYPE_CHECKING
|
||||||
|
from typing import NoReturn
|
||||||
|
from typing import Type
|
||||||
|
|
||||||
LOG = logging.getLogger(__name__)
|
LOG = logging.getLogger(__name__)
|
||||||
|
|
||||||
_NOARG = object()
|
# represent a singleton of "not passed arguments".
|
||||||
|
# an enum is chosen to trick mypy
|
||||||
|
_ARG = enum.Enum("_ARG", "NO")
|
||||||
|
|
||||||
|
|
||||||
|
_optparse_callable_map = {
|
||||||
|
"int": int,
|
||||||
|
"long": int,
|
||||||
|
"string": str,
|
||||||
|
"float": float,
|
||||||
|
"complex": complex,
|
||||||
|
"choice": _ARG.NO,
|
||||||
|
} # type: Dict[str, Union[Type[Any], _ARG]]
|
||||||
|
|
||||||
|
|
||||||
class _CallbackAction(argparse.Action):
|
class _CallbackAction(argparse.Action):
|
||||||
"""Shim for optparse-style callback actions."""
|
"""Shim for optparse-style callback actions."""
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
|
# type: (*Any, **Any) -> None
|
||||||
self._callback = kwargs.pop("callback")
|
self._callback = kwargs.pop("callback")
|
||||||
self._callback_args = kwargs.pop("callback_args", ())
|
self._callback_args = kwargs.pop("callback_args", ())
|
||||||
self._callback_kwargs = kwargs.pop("callback_kwargs", {})
|
self._callback_kwargs = kwargs.pop("callback_kwargs", {})
|
||||||
super(_CallbackAction, self).__init__(*args, **kwargs)
|
super(_CallbackAction, self).__init__(*args, **kwargs)
|
||||||
|
|
||||||
def __call__(self, parser, namespace, values, option_string=None):
|
def __call__(
|
||||||
|
self,
|
||||||
|
parser, # type: argparse.ArgumentParser
|
||||||
|
namespace, # type: argparse.Namespace
|
||||||
|
values, # type: Optional[Union[Sequence[str], str]]
|
||||||
|
option_string=None, # type: Optional[str]
|
||||||
|
):
|
||||||
|
# type: (...) -> None
|
||||||
if not values:
|
if not values:
|
||||||
values = None
|
values = None
|
||||||
elif isinstance(values, list) and len(values) > 1:
|
elif isinstance(values, list) and len(values) > 1:
|
||||||
|
|
@ -38,21 +64,23 @@ class _CallbackAction(argparse.Action):
|
||||||
|
|
||||||
|
|
||||||
def _flake8_normalize(value, *args, **kwargs):
|
def _flake8_normalize(value, *args, **kwargs):
|
||||||
|
# type: (str, *str, **bool) -> Union[str, List[str]]
|
||||||
comma_separated_list = kwargs.pop("comma_separated_list", False)
|
comma_separated_list = kwargs.pop("comma_separated_list", False)
|
||||||
normalize_paths = kwargs.pop("normalize_paths", False)
|
normalize_paths = kwargs.pop("normalize_paths", False)
|
||||||
if kwargs:
|
if kwargs:
|
||||||
raise TypeError("Unexpected keyword args: {}".format(kwargs))
|
raise TypeError("Unexpected keyword args: {}".format(kwargs))
|
||||||
|
|
||||||
if comma_separated_list and isinstance(value, utils.string_types):
|
ret = value # type: Union[str, List[str]]
|
||||||
value = utils.parse_comma_separated_list(value)
|
if comma_separated_list and isinstance(ret, utils.string_types):
|
||||||
|
ret = utils.parse_comma_separated_list(value)
|
||||||
|
|
||||||
if normalize_paths:
|
if normalize_paths:
|
||||||
if isinstance(value, list):
|
if isinstance(ret, utils.string_types):
|
||||||
value = utils.normalize_paths(value, *args)
|
ret = utils.normalize_path(ret, *args)
|
||||||
else:
|
else:
|
||||||
value = utils.normalize_path(value, *args)
|
ret = utils.normalize_paths(ret, *args)
|
||||||
|
|
||||||
return value
|
return ret
|
||||||
|
|
||||||
|
|
||||||
class Option(object):
|
class Option(object):
|
||||||
|
|
@ -60,29 +88,29 @@ class Option(object):
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
short_option_name=_NOARG,
|
short_option_name=_ARG.NO, # type: Union[str, _ARG]
|
||||||
long_option_name=_NOARG,
|
long_option_name=_ARG.NO, # type: Union[str, _ARG]
|
||||||
# Options below here are taken from the optparse.Option class
|
# Options below here are taken from the optparse.Option class
|
||||||
action=_NOARG,
|
action=_ARG.NO, # type: Union[str, Type[argparse.Action], _ARG]
|
||||||
default=_NOARG,
|
default=_ARG.NO, # type: Union[Any, _ARG]
|
||||||
type=_NOARG,
|
type=_ARG.NO, # type: Union[str, Callable[..., Any], _ARG]
|
||||||
dest=_NOARG,
|
dest=_ARG.NO, # type: Union[str, _ARG]
|
||||||
nargs=_NOARG,
|
nargs=_ARG.NO, # type: Union[int, str, _ARG]
|
||||||
const=_NOARG,
|
const=_ARG.NO, # type: Union[Any, _ARG]
|
||||||
choices=_NOARG,
|
choices=_ARG.NO, # type: Union[Sequence[Any], _ARG]
|
||||||
help=_NOARG,
|
help=_ARG.NO, # type: Union[str, _ARG]
|
||||||
metavar=_NOARG,
|
metavar=_ARG.NO, # type: Union[str, _ARG]
|
||||||
# deprecated optparse-only options
|
# deprecated optparse-only options
|
||||||
callback=_NOARG,
|
callback=_ARG.NO, # type: Union[Callable[..., Any], _ARG]
|
||||||
callback_args=_NOARG,
|
callback_args=_ARG.NO, # type: Union[Sequence[Any], _ARG]
|
||||||
callback_kwargs=_NOARG,
|
callback_kwargs=_ARG.NO, # type: Union[Mapping[str, Any], _ARG]
|
||||||
# Options below are taken from argparse.ArgumentParser.add_argument
|
# Options below are taken from argparse.ArgumentParser.add_argument
|
||||||
required=_NOARG,
|
required=_ARG.NO, # type: Union[bool, _ARG]
|
||||||
# Options below here are specific to Flake8
|
# Options below here are specific to Flake8
|
||||||
parse_from_config=False,
|
parse_from_config=False, # type: bool
|
||||||
comma_separated_list=False,
|
comma_separated_list=False, # type: bool
|
||||||
normalize_paths=False,
|
normalize_paths=False, # type: bool
|
||||||
):
|
): # type: (...) -> None
|
||||||
"""Initialize an Option instance.
|
"""Initialize an Option instance.
|
||||||
|
|
||||||
The following are all passed directly through to argparse.
|
The following are all passed directly through to argparse.
|
||||||
|
|
@ -144,11 +172,15 @@ class Option(object):
|
||||||
Whether the option is expecting a path or list of paths and should
|
Whether the option is expecting a path or list of paths and should
|
||||||
attempt to normalize the paths to absolute paths.
|
attempt to normalize the paths to absolute paths.
|
||||||
"""
|
"""
|
||||||
if long_option_name is _NOARG and short_option_name.startswith("--"):
|
if (
|
||||||
short_option_name, long_option_name = _NOARG, short_option_name
|
long_option_name is _ARG.NO
|
||||||
|
and short_option_name is not _ARG.NO
|
||||||
|
and short_option_name.startswith("--")
|
||||||
|
):
|
||||||
|
short_option_name, long_option_name = _ARG.NO, short_option_name
|
||||||
|
|
||||||
# optparse -> argparse `%default` => `%(default)s`
|
# optparse -> argparse `%default` => `%(default)s`
|
||||||
if help is not _NOARG and "%default" in help:
|
if help is not _ARG.NO and "%default" in help:
|
||||||
LOG.warning(
|
LOG.warning(
|
||||||
"option %s: please update `help=` text to use %%(default)s "
|
"option %s: please update `help=` text to use %%(default)s "
|
||||||
"instead of %%default -- this will be an error in the future",
|
"instead of %%default -- this will be an error in the future",
|
||||||
|
|
@ -165,7 +197,7 @@ class Option(object):
|
||||||
long_option_name,
|
long_option_name,
|
||||||
)
|
)
|
||||||
action = _CallbackAction
|
action = _CallbackAction
|
||||||
if type is _NOARG:
|
if type is _ARG.NO:
|
||||||
nargs = 0
|
nargs = 0
|
||||||
|
|
||||||
# optparse -> argparse for `type`
|
# optparse -> argparse for `type`
|
||||||
|
|
@ -175,14 +207,7 @@ class Option(object):
|
||||||
"argparse callable `type=` -- this will be an error in the "
|
"argparse callable `type=` -- this will be an error in the "
|
||||||
"future"
|
"future"
|
||||||
)
|
)
|
||||||
type = {
|
type = _optparse_callable_map[type]
|
||||||
"int": int,
|
|
||||||
"long": int,
|
|
||||||
"string": str,
|
|
||||||
"float": float,
|
|
||||||
"complex": complex,
|
|
||||||
"choice": _NOARG,
|
|
||||||
}[type]
|
|
||||||
|
|
||||||
# flake8 special type normalization
|
# flake8 special type normalization
|
||||||
if comma_separated_list or normalize_paths:
|
if comma_separated_list or normalize_paths:
|
||||||
|
|
@ -197,25 +222,36 @@ class Option(object):
|
||||||
self.option_args = [
|
self.option_args = [
|
||||||
x
|
x
|
||||||
for x in (short_option_name, long_option_name)
|
for x in (short_option_name, long_option_name)
|
||||||
if x is not _NOARG
|
if x is not _ARG.NO
|
||||||
]
|
]
|
||||||
|
self.action = action
|
||||||
|
self.default = default
|
||||||
|
self.type = type
|
||||||
|
self.dest = dest
|
||||||
|
self.nargs = nargs
|
||||||
|
self.const = const
|
||||||
|
self.choices = choices
|
||||||
|
self.callback = callback
|
||||||
|
self.callback_args = callback_args
|
||||||
|
self.callback_kwargs = callback_kwargs
|
||||||
|
self.help = help
|
||||||
|
self.metavar = metavar
|
||||||
|
self.required = required
|
||||||
self.option_kwargs = {
|
self.option_kwargs = {
|
||||||
"action": action,
|
"action": self.action,
|
||||||
"default": default,
|
"default": self.default,
|
||||||
"type": type,
|
"type": self.type,
|
||||||
"dest": dest,
|
"dest": self.dest,
|
||||||
"nargs": nargs,
|
"nargs": self.nargs,
|
||||||
"const": const,
|
"const": self.const,
|
||||||
"choices": choices,
|
"choices": self.choices,
|
||||||
"callback": callback,
|
"callback": self.callback,
|
||||||
"callback_args": callback_args,
|
"callback_args": self.callback_args,
|
||||||
"callback_kwargs": callback_kwargs,
|
"callback_kwargs": self.callback_kwargs,
|
||||||
"help": help,
|
"help": self.help,
|
||||||
"metavar": metavar,
|
"metavar": self.metavar,
|
||||||
}
|
"required": self.required,
|
||||||
# Set attributes for our option arguments
|
} # type: Dict[str, Union[Any, _ARG]]
|
||||||
for key, value in self.option_kwargs.items():
|
|
||||||
setattr(self, key, value)
|
|
||||||
|
|
||||||
# Set our custom attributes
|
# Set our custom attributes
|
||||||
self.parse_from_config = parse_from_config
|
self.parse_from_config = parse_from_config
|
||||||
|
|
@ -224,7 +260,7 @@ class Option(object):
|
||||||
|
|
||||||
self.config_name = None # type: Optional[str]
|
self.config_name = None # type: Optional[str]
|
||||||
if parse_from_config:
|
if parse_from_config:
|
||||||
if long_option_name is _NOARG:
|
if long_option_name is _ARG.NO:
|
||||||
raise ValueError(
|
raise ValueError(
|
||||||
"When specifying parse_from_config=True, "
|
"When specifying parse_from_config=True, "
|
||||||
"a long_option_name must also be specified."
|
"a long_option_name must also be specified."
|
||||||
|
|
@ -237,10 +273,10 @@ class Option(object):
|
||||||
def filtered_option_kwargs(self): # type: () -> Dict[str, Any]
|
def filtered_option_kwargs(self): # type: () -> Dict[str, Any]
|
||||||
"""Return any actually-specified arguments."""
|
"""Return any actually-specified arguments."""
|
||||||
return {
|
return {
|
||||||
k: v for k, v in self.option_kwargs.items() if v is not _NOARG
|
k: v for k, v in self.option_kwargs.items() if v is not _ARG.NO
|
||||||
}
|
}
|
||||||
|
|
||||||
def __repr__(self): # noqa: D105
|
def __repr__(self): # type: () -> str # noqa: D105
|
||||||
parts = []
|
parts = []
|
||||||
for arg in self.option_args:
|
for arg in self.option_args:
|
||||||
parts.append(arg)
|
parts.append(arg)
|
||||||
|
|
@ -249,6 +285,7 @@ class Option(object):
|
||||||
return "Option({})".format(", ".join(parts))
|
return "Option({})".format(", ".join(parts))
|
||||||
|
|
||||||
def normalize(self, value, *normalize_args):
|
def normalize(self, value, *normalize_args):
|
||||||
|
# type: (Any, *str) -> Any
|
||||||
"""Normalize the value based on the option configuration."""
|
"""Normalize the value based on the option configuration."""
|
||||||
if self.comma_separated_list and isinstance(
|
if self.comma_separated_list and isinstance(
|
||||||
value, utils.string_types
|
value, utils.string_types
|
||||||
|
|
@ -264,6 +301,7 @@ class Option(object):
|
||||||
return value
|
return value
|
||||||
|
|
||||||
def normalize_from_setuptools(self, value):
|
def normalize_from_setuptools(self, value):
|
||||||
|
# type: (str) -> Union[int, float, complex, bool, str]
|
||||||
"""Normalize the value received from setuptools."""
|
"""Normalize the value received from setuptools."""
|
||||||
value = self.normalize(value)
|
value = self.normalize(value)
|
||||||
if self.type is int or self.action == "count":
|
if self.type is int or self.action == "count":
|
||||||
|
|
@ -281,11 +319,12 @@ class Option(object):
|
||||||
return value
|
return value
|
||||||
|
|
||||||
def to_argparse(self):
|
def to_argparse(self):
|
||||||
|
# type: () -> Tuple[List[str], Dict[str, Any]]
|
||||||
"""Convert a Flake8 Option to argparse ``add_argument`` arguments."""
|
"""Convert a Flake8 Option to argparse ``add_argument`` arguments."""
|
||||||
return self.option_args, self.filtered_option_kwargs
|
return self.option_args, self.filtered_option_kwargs
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def to_optparse(self):
|
def to_optparse(self): # type: () -> NoReturn
|
||||||
"""No longer functional."""
|
"""No longer functional."""
|
||||||
raise AttributeError("to_optparse: flake8 now uses argparse")
|
raise AttributeError("to_optparse: flake8 now uses argparse")
|
||||||
|
|
||||||
|
|
@ -299,11 +338,8 @@ class OptionManager(object):
|
||||||
"""Manage Options and OptionParser while adding post-processing."""
|
"""Manage Options and OptionParser while adding post-processing."""
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self, prog, version, usage="%(prog)s [options] file file ..."
|
||||||
prog=None,
|
): # type: (str, str, str) -> None
|
||||||
version=None,
|
|
||||||
usage="%(prog)s [options] file file ...",
|
|
||||||
):
|
|
||||||
"""Initialize an instance of an OptionManager.
|
"""Initialize an instance of an OptionManager.
|
||||||
|
|
||||||
:param str prog:
|
:param str prog:
|
||||||
|
|
@ -315,9 +351,13 @@ class OptionManager(object):
|
||||||
"""
|
"""
|
||||||
self.parser = argparse.ArgumentParser(
|
self.parser = argparse.ArgumentParser(
|
||||||
prog=prog, usage=usage
|
prog=prog, usage=usage
|
||||||
) # type: Union[argparse.ArgumentParser, argparse._ArgumentGroup]
|
) # type: argparse.ArgumentParser
|
||||||
self.version_action = self.parser.add_argument(
|
self._current_group = None # type: Optional[argparse._ArgumentGroup]
|
||||||
|
self.version_action = cast(
|
||||||
|
"argparse._VersionAction",
|
||||||
|
self.parser.add_argument(
|
||||||
"--version", action="version", version=version
|
"--version", action="version", version=version
|
||||||
|
),
|
||||||
)
|
)
|
||||||
self.parser.add_argument("filenames", nargs="*", metavar="filename")
|
self.parser.add_argument("filenames", nargs="*", metavar="filename")
|
||||||
self.config_options_dict = {} # type: Dict[str, Option]
|
self.config_options_dict = {} # type: Dict[str, Option]
|
||||||
|
|
@ -328,22 +368,17 @@ class OptionManager(object):
|
||||||
self.extended_default_ignore = set() # type: Set[str]
|
self.extended_default_ignore = set() # type: Set[str]
|
||||||
self.extended_default_select = set() # type: Set[str]
|
self.extended_default_select = set() # type: Set[str]
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def format_plugin(plugin):
|
|
||||||
"""Convert a PluginVersion into a dictionary mapping name to value."""
|
|
||||||
return {attr: getattr(plugin, attr) for attr in ["name", "version"]}
|
|
||||||
|
|
||||||
@contextlib.contextmanager
|
@contextlib.contextmanager
|
||||||
def group(self, name): # type: (str) -> Generator[None, None, None]
|
def group(self, name): # type: (str) -> Generator[None, None, None]
|
||||||
"""Attach options to an argparse group during this context."""
|
"""Attach options to an argparse group during this context."""
|
||||||
group = self.parser.add_argument_group(name)
|
group = self.parser.add_argument_group(name)
|
||||||
self.parser, orig_parser = group, self.parser
|
self._current_group, orig_group = group, self._current_group
|
||||||
try:
|
try:
|
||||||
yield
|
yield
|
||||||
finally:
|
finally:
|
||||||
self.parser = orig_parser
|
self._current_group = orig_group
|
||||||
|
|
||||||
def add_option(self, *args, **kwargs):
|
def add_option(self, *args, **kwargs): # type: (*Any, **Any) -> None
|
||||||
"""Create and register a new option.
|
"""Create and register a new option.
|
||||||
|
|
||||||
See parameters for :class:`~flake8.options.manager.Option` for
|
See parameters for :class:`~flake8.options.manager.Option` for
|
||||||
|
|
@ -356,6 +391,9 @@ class OptionManager(object):
|
||||||
"""
|
"""
|
||||||
option = Option(*args, **kwargs)
|
option = Option(*args, **kwargs)
|
||||||
option_args, option_kwargs = option.to_argparse()
|
option_args, option_kwargs = option.to_argparse()
|
||||||
|
if self._current_group is not None:
|
||||||
|
self._current_group.add_argument(*option_args, **option_kwargs)
|
||||||
|
else:
|
||||||
self.parser.add_argument(*option_args, **option_kwargs)
|
self.parser.add_argument(*option_args, **option_kwargs)
|
||||||
self.options.append(option)
|
self.options.append(option)
|
||||||
if option.parse_from_config:
|
if option.parse_from_config:
|
||||||
|
|
@ -366,6 +404,7 @@ class OptionManager(object):
|
||||||
LOG.debug('Registered option "%s".', option)
|
LOG.debug('Registered option "%s".', option)
|
||||||
|
|
||||||
def remove_from_default_ignore(self, error_codes):
|
def remove_from_default_ignore(self, error_codes):
|
||||||
|
# type: (Sequence[str]) -> None
|
||||||
"""Remove specified error codes from the default ignore list.
|
"""Remove specified error codes from the default ignore list.
|
||||||
|
|
||||||
:param list error_codes:
|
:param list error_codes:
|
||||||
|
|
@ -384,6 +423,7 @@ class OptionManager(object):
|
||||||
)
|
)
|
||||||
|
|
||||||
def extend_default_ignore(self, error_codes):
|
def extend_default_ignore(self, error_codes):
|
||||||
|
# type: (Sequence[str]) -> None
|
||||||
"""Extend the default ignore list with the error codes provided.
|
"""Extend the default ignore list with the error codes provided.
|
||||||
|
|
||||||
:param list error_codes:
|
:param list error_codes:
|
||||||
|
|
@ -394,6 +434,7 @@ class OptionManager(object):
|
||||||
self.extended_default_ignore.update(error_codes)
|
self.extended_default_ignore.update(error_codes)
|
||||||
|
|
||||||
def extend_default_select(self, error_codes):
|
def extend_default_select(self, error_codes):
|
||||||
|
# type: (Sequence[str]) -> None
|
||||||
"""Extend the default select list with the error codes provided.
|
"""Extend the default select list with the error codes provided.
|
||||||
|
|
||||||
:param list error_codes:
|
:param list error_codes:
|
||||||
|
|
@ -406,19 +447,20 @@ class OptionManager(object):
|
||||||
def generate_versions(
|
def generate_versions(
|
||||||
self, format_str="%(name)s: %(version)s", join_on=", "
|
self, format_str="%(name)s: %(version)s", join_on=", "
|
||||||
):
|
):
|
||||||
|
# type: (str, str) -> str
|
||||||
"""Generate a comma-separated list of versions of plugins."""
|
"""Generate a comma-separated list of versions of plugins."""
|
||||||
return join_on.join(
|
return join_on.join(
|
||||||
format_str % self.format_plugin(plugin)
|
format_str % plugin._asdict()
|
||||||
for plugin in sorted(self.registered_plugins)
|
for plugin in sorted(self.registered_plugins)
|
||||||
)
|
)
|
||||||
|
|
||||||
def update_version_string(self):
|
def update_version_string(self): # type: () -> None
|
||||||
"""Update the flake8 version string."""
|
"""Update the flake8 version string."""
|
||||||
self.version_action.version = "{} ({}) {}".format(
|
self.version_action.version = "{} ({}) {}".format(
|
||||||
self.version, self.generate_versions(), utils.get_python_version()
|
self.version, self.generate_versions(), utils.get_python_version()
|
||||||
)
|
)
|
||||||
|
|
||||||
def generate_epilog(self):
|
def generate_epilog(self): # type: () -> None
|
||||||
"""Create an epilog with the version and name of each of plugin."""
|
"""Create an epilog with the version and name of each of plugin."""
|
||||||
plugin_version_format = "%(name)s: %(version)s"
|
plugin_version_format = "%(name)s: %(version)s"
|
||||||
self.parser.epilog = "Installed plugins: " + self.generate_versions(
|
self.parser.epilog = "Installed plugins: " + self.generate_versions(
|
||||||
|
|
@ -434,9 +476,6 @@ class OptionManager(object):
|
||||||
"""Proxy to calling the OptionParser's parse_args method."""
|
"""Proxy to calling the OptionParser's parse_args method."""
|
||||||
self.generate_epilog()
|
self.generate_epilog()
|
||||||
self.update_version_string()
|
self.update_version_string()
|
||||||
assert isinstance( # nosec (for bandit)
|
|
||||||
self.parser, argparse.ArgumentParser
|
|
||||||
), self.parser
|
|
||||||
if values:
|
if values:
|
||||||
self.parser.set_defaults(**vars(values))
|
self.parser.set_defaults(**vars(values))
|
||||||
parsed_args = self.parser.parse_args(args)
|
parsed_args = self.parser.parse_args(args)
|
||||||
|
|
@ -452,14 +491,10 @@ class OptionManager(object):
|
||||||
"""
|
"""
|
||||||
self.generate_epilog()
|
self.generate_epilog()
|
||||||
self.update_version_string()
|
self.update_version_string()
|
||||||
# TODO: Re-evaluate `self.parser` swap happening in `group()` to
|
|
||||||
# avoid needing to assert to satify static type checking.
|
|
||||||
assert isinstance( # nosec (for bandit)
|
|
||||||
self.parser, argparse.ArgumentParser
|
|
||||||
), self.parser
|
|
||||||
return self.parser.parse_known_args(args)
|
return self.parser.parse_known_args(args)
|
||||||
|
|
||||||
def register_plugin(self, name, version, local=False):
|
def register_plugin(self, name, version, local=False):
|
||||||
|
# type: (str, str, bool) -> None
|
||||||
"""Register a plugin relying on the OptionManager.
|
"""Register a plugin relying on the OptionManager.
|
||||||
|
|
||||||
:param str name:
|
:param str name:
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
"""Plugin loading and management logic and classes."""
|
"""Plugin loading and management logic and classes."""
|
||||||
import logging
|
import logging
|
||||||
from typing import Any, Dict, List, Set
|
from typing import Any, Dict, List, Optional, Set
|
||||||
|
|
||||||
import entrypoints
|
import entrypoints
|
||||||
|
|
||||||
|
|
@ -34,12 +34,12 @@ class Plugin(object):
|
||||||
self.local = local
|
self.local = local
|
||||||
self._plugin = None # type: Any
|
self._plugin = None # type: Any
|
||||||
self._parameters = None
|
self._parameters = None
|
||||||
self._parameter_names = None
|
self._parameter_names = None # type: Optional[List[str]]
|
||||||
self._group = None
|
self._group = None
|
||||||
self._plugin_name = None
|
self._plugin_name = None
|
||||||
self._version = None
|
self._version = None
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self): # type: () -> str
|
||||||
"""Provide an easy to read description of the current plugin."""
|
"""Provide an easy to read description of the current plugin."""
|
||||||
return 'Plugin(name="{0}", entry_point="{1}")'.format(
|
return 'Plugin(name="{0}", entry_point="{1}")'.format(
|
||||||
self.name, self.entry_point
|
self.name, self.entry_point
|
||||||
|
|
@ -85,7 +85,7 @@ class Plugin(object):
|
||||||
return self._parameters
|
return self._parameters
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def parameter_names(self):
|
def parameter_names(self): # type: () -> List[str]
|
||||||
"""List of argument names that need to be passed to the plugin."""
|
"""List of argument names that need to be passed to the plugin."""
|
||||||
if self._parameter_names is None:
|
if self._parameter_names is None:
|
||||||
self._parameter_names = list(self.parameters)
|
self._parameter_names = list(self.parameters)
|
||||||
|
|
@ -101,15 +101,15 @@ class Plugin(object):
|
||||||
return self._plugin
|
return self._plugin
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def version(self):
|
def version(self): # type: () -> str
|
||||||
"""Return the version of the plugin."""
|
"""Return the version of the plugin."""
|
||||||
if self._version is None:
|
version = self._version
|
||||||
|
if version is None:
|
||||||
if self.is_in_a_group():
|
if self.is_in_a_group():
|
||||||
self._version = version_for(self)
|
version = self._version = version_for(self)
|
||||||
else:
|
else:
|
||||||
self._version = self.plugin.version
|
version = self._version = self.plugin.version
|
||||||
|
return version
|
||||||
return self._version
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def plugin_name(self):
|
def plugin_name(self):
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,6 @@ else:
|
||||||
from functools import lru_cache
|
from functools import lru_cache
|
||||||
|
|
||||||
|
|
||||||
# TODO(sigmavirus24): Determine if we need to use enum/enum34
|
|
||||||
class Selected(enum.Enum):
|
class Selected(enum.Enum):
|
||||||
"""Enum representing an explicitly or implicitly selected code."""
|
"""Enum representing an explicitly or implicitly selected code."""
|
||||||
|
|
||||||
|
|
@ -451,7 +450,7 @@ class StyleGuide(object):
|
||||||
self.filename = utils.normalize_path(self.filename)
|
self.filename = utils.normalize_path(self.filename)
|
||||||
self._parsed_diff = {} # type: Dict[str, Set[int]]
|
self._parsed_diff = {} # type: Dict[str, Set[int]]
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self): # type: () -> str
|
||||||
"""Make it easier to debug which StyleGuide we're using."""
|
"""Make it easier to debug which StyleGuide we're using."""
|
||||||
return "<StyleGuide [{}]>".format(self.filename)
|
return "<StyleGuide [{}]>".format(self.filename)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@ def test_to_argparse():
|
||||||
def test_to_optparse():
|
def test_to_optparse():
|
||||||
"""Test that .to_optparse() produces a useful error message."""
|
"""Test that .to_optparse() produces a useful error message."""
|
||||||
with pytest.raises(AttributeError) as excinfo:
|
with pytest.raises(AttributeError) as excinfo:
|
||||||
manager.Option('--foo').to_optparse()
|
manager.Option('--foo').to_optparse
|
||||||
msg, = excinfo.value.args
|
msg, = excinfo.value.args
|
||||||
assert msg == 'to_optparse: flake8 now uses argparse'
|
assert msg == 'to_optparse: flake8 now uses argparse'
|
||||||
|
|
||||||
|
|
@ -58,4 +58,4 @@ def test_config_name_needs_long_option_name():
|
||||||
def test_dest_is_not_overridden():
|
def test_dest_is_not_overridden():
|
||||||
"""Show that we do not override custom destinations."""
|
"""Show that we do not override custom destinations."""
|
||||||
opt = manager.Option('-s', '--short', dest='something_not_short')
|
opt = manager.Option('-s', '--short', dest='something_not_short')
|
||||||
assert opt.dest == 'something_not_short' # type: ignore
|
assert opt.dest == 'something_not_short'
|
||||||
|
|
|
||||||
|
|
@ -52,7 +52,7 @@ def test_add_option_long_option_only(optmanager):
|
||||||
assert optmanager.config_options_dict == {}
|
assert optmanager.config_options_dict == {}
|
||||||
|
|
||||||
optmanager.add_option('--long', help='Test long opt')
|
optmanager.add_option('--long', help='Test long opt')
|
||||||
assert optmanager.options[0].short_option_name is manager._NOARG
|
assert optmanager.options[0].short_option_name is manager._ARG.NO
|
||||||
assert optmanager.options[0].long_option_name == '--long'
|
assert optmanager.options[0].long_option_name == '--long'
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -133,15 +133,6 @@ def test_parse_args_normalize_paths(optmanager):
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
def test_format_plugin():
|
|
||||||
"""Verify that format_plugin turns a tuple into a dictionary."""
|
|
||||||
plugin = manager.OptionManager.format_plugin(
|
|
||||||
manager.PluginVersion('Testing', '0.0.0', False)
|
|
||||||
)
|
|
||||||
assert plugin['name'] == 'Testing'
|
|
||||||
assert plugin['version'] == '0.0.0'
|
|
||||||
|
|
||||||
|
|
||||||
def test_generate_versions(optmanager):
|
def test_generate_versions(optmanager):
|
||||||
"""Verify a comma-separated string is generated of registered plugins."""
|
"""Verify a comma-separated string is generated of registered plugins."""
|
||||||
optmanager.registered_plugins = [
|
optmanager.registered_plugins = [
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue