move managing of off_by_default / enable_extensions to plugin loading

This commit is contained in:
Anthony Sottile 2022-01-01 18:28:11 -05:00
parent ff13916d74
commit a8333e2bf2
12 changed files with 137 additions and 111 deletions

View file

@ -38,7 +38,7 @@ def get_style_guide(**kwargs):
isolated=prelim_opts.isolated,
)
application.find_plugins(cfg, cfg_dir)
application.find_plugins(cfg, cfg_dir, prelim_opts.enable_extensions)
application.register_plugin_options()
application.parse_configuration_and_cli(cfg, cfg_dir, remaining_args)
# We basically want application.initialize to be called but with these

View file

@ -119,14 +119,16 @@ class Application:
self,
cfg: configparser.RawConfigParser,
cfg_dir: str,
enable_extensions: Optional[str],
) -> None:
"""Find and load the plugins for this application.
Set :attr:`plugins` based on loaded plugins.
"""
raw_plugins = finder.find_plugins(cfg)
raw = finder.find_plugins(cfg)
local_plugin_paths = finder.find_local_plugin_paths(cfg, cfg_dir)
self.plugins = finder.load_plugins(raw_plugins, local_plugin_paths)
enabled = finder.parse_enabled(cfg, enable_extensions)
self.plugins = finder.load_plugins(raw, local_plugin_paths, enabled)
def register_plugin_options(self) -> None:
"""Register options provided by plugins to our option manager."""
@ -302,7 +304,7 @@ class Application:
isolated=prelim_opts.isolated,
)
self.find_plugins(cfg, cfg_dir)
self.find_plugins(cfg, cfg_dir, prelim_opts.enable_extensions)
self.register_plugin_options()
self.parse_configuration_and_cli(cfg, cfg_dir, remaining_args)
self.make_formatter()

View file

@ -15,6 +15,7 @@ def stage1_arg_parser() -> argparse.ArgumentParser:
- ``--append-config``
- ``--config``
- ``--isolated``
- ``--enable-extensions``
"""
parser = argparse.ArgumentParser(add_help=False)
@ -59,6 +60,14 @@ def stage1_arg_parser() -> argparse.ArgumentParser:
help="Ignore all configuration files.",
)
# Plugin enablement options
parser.add_argument(
"--enable-extensions",
help="Enable plugins and extensions that are otherwise disabled "
"by default",
)
return parser
@ -116,7 +125,6 @@ def register_default_options(option_manager: OptionManager) -> None:
- ``--disable-noqa``
- ``--show-source``
- ``--statistics``
- ``--enable-extensions``
- ``--exit-zero``
- ``-j``/``--jobs``
- ``--tee``
@ -331,14 +339,6 @@ def register_default_options(option_manager: OptionManager) -> None:
)
# Flake8 options
add_option(
"--enable-extensions",
default="",
parse_from_config=True,
comma_separated_list=True,
help="Enable plugins and extensions that are otherwise disabled "
"by default",
)
add_option(
"--exit-zero",

View file

@ -376,11 +376,7 @@ class OptionManager:
_set_group(loaded.plugin.package)
add_options(self)
# if the plugin is off by default, disable it!
if getattr(loaded.obj, "off_by_default", False):
self.extend_default_ignore(loaded.entry_name)
else:
self.extend_default_select(loaded.entry_name)
self.extend_default_select(loaded.entry_name)
# isn't strictly necessary, but seems cleaner
self._current_group = None

View file

@ -9,6 +9,8 @@ from typing import Generator
from typing import Iterable
from typing import List
from typing import NamedTuple
from typing import Optional
from typing import Set
from flake8 import utils
from flake8._compat import importlib_metadata
@ -63,6 +65,7 @@ class Plugins(NamedTuple):
checkers: Checkers
reporters: Dict[str, LoadedPlugin]
disabled: List[LoadedPlugin]
def all_plugins(self) -> Generator[LoadedPlugin, None, None]:
"""Return an iterator over all :class:`LoadedPlugin`s."""
@ -171,6 +174,24 @@ def find_local_plugin_paths(
return utils.normalize_paths(paths, cfg_dir)
def parse_enabled(
cfg: configparser.RawConfigParser,
enable_extensions: Optional[str],
) -> Set[str]:
"""Parse --enable-extensions."""
if enable_extensions is not None:
return set(utils.parse_comma_separated_list(enable_extensions))
else:
# ideally this would reuse our config parsing framework but we need to
# parse this from preliminary options before plugins are enabled
for opt in ("enable_extensions", "enable-extensions"):
val = cfg.get("flake8", opt, fallback=None)
if val is not None:
return set(utils.parse_comma_separated_list(val))
else:
return set()
def _parameters_for(func: Any) -> Dict[str, bool]:
"""Return the parameters for the plugin.
@ -218,14 +239,23 @@ def _import_plugins(
return [_load_plugin(p) for p in plugins]
def _classify_plugins(plugins: List[LoadedPlugin]) -> Plugins:
def _classify_plugins(
plugins: List[LoadedPlugin],
enabled: Set[str],
) -> Plugins:
tree = []
logical_line = []
physical_line = []
reporters = {}
disabled = []
for loaded in plugins:
if loaded.plugin.entry_point.group == "flake8.report":
if (
getattr(loaded.obj, "off_by_default", False)
and loaded.plugin.entry_point.name not in enabled
):
disabled.append(loaded)
elif loaded.plugin.entry_point.group == "flake8.report":
reporters[loaded.entry_name] = loaded
elif "tree" in loaded.parameters:
tree.append(loaded)
@ -243,14 +273,19 @@ def _classify_plugins(plugins: List[LoadedPlugin]) -> Plugins:
physical_line=physical_line,
),
reporters=reporters,
disabled=disabled,
)
def load_plugins(plugins: List[Plugin], paths: List[str]) -> Plugins:
def load_plugins(
plugins: List[Plugin],
paths: List[str],
enabled: Set[str],
) -> Plugins:
"""Load and classify all flake8 plugins.
- first: extends ``sys.path`` with ``paths`` (to import local plugins)
- next: converts the ``Plugin``s to ``LoadedPlugins``
- finally: classifies plugins into their specific types
"""
return _classify_plugins(_import_plugins(plugins, paths))
return _classify_plugins(_import_plugins(plugins, paths), enabled)

View file

@ -160,14 +160,9 @@ class DecisionEngine:
self.extended_selected = tuple(
sorted(options.extended_default_select, reverse=True)
)
self.enabled_extensions = tuple(options.enable_extensions)
self.all_selected = tuple(
sorted(
itertools.chain(
self.selected,
options.extend_select,
self.enabled_extensions,
),
itertools.chain(self.selected, options.extend_select),
reverse=True,
)
)