mirror of
https://github.com/pacnpal/thrillwiki_django_no_react.git
synced 2025-12-22 04:51:09 -05:00
okay fine
This commit is contained in:
@@ -0,0 +1,2 @@
|
||||
"""Submodule of built-in plugins and plugin managers."""
|
||||
from __future__ import annotations
|
||||
365
.venv/lib/python3.12/site-packages/flake8/plugins/finder.py
Normal file
365
.venv/lib/python3.12/site-packages/flake8/plugins/finder.py
Normal file
@@ -0,0 +1,365 @@
|
||||
"""Functions related to finding and loading plugins."""
|
||||
from __future__ import annotations
|
||||
|
||||
import configparser
|
||||
import importlib.metadata
|
||||
import inspect
|
||||
import itertools
|
||||
import logging
|
||||
import sys
|
||||
from typing import Any
|
||||
from typing import Generator
|
||||
from typing import Iterable
|
||||
from typing import NamedTuple
|
||||
|
||||
from flake8 import utils
|
||||
from flake8.defaults import VALID_CODE_PREFIX
|
||||
from flake8.exceptions import ExecutionError
|
||||
from flake8.exceptions import FailedToLoadPlugin
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
FLAKE8_GROUPS = frozenset(("flake8.extension", "flake8.report"))
|
||||
|
||||
BANNED_PLUGINS = {
|
||||
"flake8-colors": "5.0",
|
||||
"flake8-per-file-ignores": "3.7",
|
||||
}
|
||||
|
||||
|
||||
class Plugin(NamedTuple):
|
||||
"""A plugin before loading."""
|
||||
|
||||
package: str
|
||||
version: str
|
||||
entry_point: importlib.metadata.EntryPoint
|
||||
|
||||
|
||||
class LoadedPlugin(NamedTuple):
|
||||
"""Represents a plugin after being imported."""
|
||||
|
||||
plugin: Plugin
|
||||
obj: Any
|
||||
parameters: dict[str, bool]
|
||||
|
||||
@property
|
||||
def entry_name(self) -> str:
|
||||
"""Return the name given in the packaging metadata."""
|
||||
return self.plugin.entry_point.name
|
||||
|
||||
@property
|
||||
def display_name(self) -> str:
|
||||
"""Return the name for use in user-facing / error messages."""
|
||||
return f"{self.plugin.package}[{self.entry_name}]"
|
||||
|
||||
|
||||
class Checkers(NamedTuple):
|
||||
"""Classified plugins needed for checking."""
|
||||
|
||||
tree: list[LoadedPlugin]
|
||||
logical_line: list[LoadedPlugin]
|
||||
physical_line: list[LoadedPlugin]
|
||||
|
||||
|
||||
class Plugins(NamedTuple):
|
||||
"""Classified plugins."""
|
||||
|
||||
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."""
|
||||
yield from self.checkers.tree
|
||||
yield from self.checkers.logical_line
|
||||
yield from self.checkers.physical_line
|
||||
yield from self.reporters.values()
|
||||
|
||||
def versions_str(self) -> str:
|
||||
"""Return a user-displayed list of plugin versions."""
|
||||
return ", ".join(
|
||||
sorted(
|
||||
{
|
||||
f"{loaded.plugin.package}: {loaded.plugin.version}"
|
||||
for loaded in self.all_plugins()
|
||||
if loaded.plugin.package not in {"flake8", "local"}
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
class PluginOptions(NamedTuple):
|
||||
"""Options related to plugin loading."""
|
||||
|
||||
local_plugin_paths: tuple[str, ...]
|
||||
enable_extensions: frozenset[str]
|
||||
require_plugins: frozenset[str]
|
||||
|
||||
@classmethod
|
||||
def blank(cls) -> PluginOptions:
|
||||
"""Make a blank PluginOptions, mostly used for tests."""
|
||||
return cls(
|
||||
local_plugin_paths=(),
|
||||
enable_extensions=frozenset(),
|
||||
require_plugins=frozenset(),
|
||||
)
|
||||
|
||||
|
||||
def _parse_option(
|
||||
cfg: configparser.RawConfigParser,
|
||||
cfg_opt_name: str,
|
||||
opt: str | None,
|
||||
) -> list[str]:
|
||||
# specified on commandline: use that
|
||||
if opt is not None:
|
||||
return utils.parse_comma_separated_list(opt)
|
||||
else:
|
||||
# ideally this would reuse our config parsing framework but we need to
|
||||
# parse this from preliminary options before plugins are enabled
|
||||
for opt_name in (cfg_opt_name, cfg_opt_name.replace("_", "-")):
|
||||
val = cfg.get("flake8", opt_name, fallback=None)
|
||||
if val is not None:
|
||||
return utils.parse_comma_separated_list(val)
|
||||
else:
|
||||
return []
|
||||
|
||||
|
||||
def parse_plugin_options(
|
||||
cfg: configparser.RawConfigParser,
|
||||
cfg_dir: str,
|
||||
*,
|
||||
enable_extensions: str | None,
|
||||
require_plugins: str | None,
|
||||
) -> PluginOptions:
|
||||
"""Parse plugin loading related options."""
|
||||
paths_s = cfg.get("flake8:local-plugins", "paths", fallback="").strip()
|
||||
paths = utils.parse_comma_separated_list(paths_s)
|
||||
paths = utils.normalize_paths(paths, cfg_dir)
|
||||
|
||||
return PluginOptions(
|
||||
local_plugin_paths=tuple(paths),
|
||||
enable_extensions=frozenset(
|
||||
_parse_option(cfg, "enable_extensions", enable_extensions),
|
||||
),
|
||||
require_plugins=frozenset(
|
||||
_parse_option(cfg, "require_plugins", require_plugins),
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
def _flake8_plugins(
|
||||
eps: Iterable[importlib.metadata.EntryPoint],
|
||||
name: str,
|
||||
version: str,
|
||||
) -> Generator[Plugin, None, None]:
|
||||
pyflakes_meta = importlib.metadata.distribution("pyflakes").metadata
|
||||
pycodestyle_meta = importlib.metadata.distribution("pycodestyle").metadata
|
||||
|
||||
for ep in eps:
|
||||
if ep.group not in FLAKE8_GROUPS:
|
||||
continue
|
||||
|
||||
if ep.name == "F":
|
||||
yield Plugin(pyflakes_meta["name"], pyflakes_meta["version"], ep)
|
||||
elif ep.name in "EW":
|
||||
# pycodestyle provides both `E` and `W` -- but our default select
|
||||
# handles those
|
||||
# ideally pycodestyle's plugin entrypoints would exactly represent
|
||||
# the codes they produce...
|
||||
yield Plugin(
|
||||
pycodestyle_meta["name"], pycodestyle_meta["version"], ep
|
||||
)
|
||||
else:
|
||||
yield Plugin(name, version, ep)
|
||||
|
||||
|
||||
def _find_importlib_plugins() -> Generator[Plugin, None, None]:
|
||||
# some misconfigured pythons (RHEL) have things on `sys.path` twice
|
||||
seen = set()
|
||||
for dist in importlib.metadata.distributions():
|
||||
# assigned to prevent continual reparsing
|
||||
eps = dist.entry_points
|
||||
|
||||
# perf: skip parsing `.metadata` (slow) if no entry points match
|
||||
if not any(ep.group in FLAKE8_GROUPS for ep in eps):
|
||||
continue
|
||||
|
||||
# assigned to prevent continual reparsing
|
||||
meta = dist.metadata
|
||||
|
||||
if meta["name"] in seen:
|
||||
continue
|
||||
else:
|
||||
seen.add(meta["name"])
|
||||
|
||||
if meta["name"] in BANNED_PLUGINS:
|
||||
LOG.warning(
|
||||
"%s plugin is obsolete in flake8>=%s",
|
||||
meta["name"],
|
||||
BANNED_PLUGINS[meta["name"]],
|
||||
)
|
||||
continue
|
||||
elif meta["name"] == "flake8":
|
||||
# special case flake8 which provides plugins for pyflakes /
|
||||
# pycodestyle
|
||||
yield from _flake8_plugins(eps, meta["name"], meta["version"])
|
||||
continue
|
||||
|
||||
for ep in eps:
|
||||
if ep.group in FLAKE8_GROUPS:
|
||||
yield Plugin(meta["name"], meta["version"], ep)
|
||||
|
||||
|
||||
def _find_local_plugins(
|
||||
cfg: configparser.RawConfigParser,
|
||||
) -> Generator[Plugin, None, None]:
|
||||
for plugin_type in ("extension", "report"):
|
||||
group = f"flake8.{plugin_type}"
|
||||
for plugin_s in utils.parse_comma_separated_list(
|
||||
cfg.get("flake8:local-plugins", plugin_type, fallback="").strip(),
|
||||
regexp=utils.LOCAL_PLUGIN_LIST_RE,
|
||||
):
|
||||
name, _, entry_str = plugin_s.partition("=")
|
||||
name, entry_str = name.strip(), entry_str.strip()
|
||||
ep = importlib.metadata.EntryPoint(name, entry_str, group)
|
||||
yield Plugin("local", "local", ep)
|
||||
|
||||
|
||||
def _check_required_plugins(
|
||||
plugins: list[Plugin],
|
||||
expected: frozenset[str],
|
||||
) -> None:
|
||||
plugin_names = {
|
||||
utils.normalize_pypi_name(plugin.package) for plugin in plugins
|
||||
}
|
||||
expected_names = {utils.normalize_pypi_name(name) for name in expected}
|
||||
missing_plugins = expected_names - plugin_names
|
||||
|
||||
if missing_plugins:
|
||||
raise ExecutionError(
|
||||
f"required plugins were not installed!\n"
|
||||
f"- installed: {', '.join(sorted(plugin_names))}\n"
|
||||
f"- expected: {', '.join(sorted(expected_names))}\n"
|
||||
f"- missing: {', '.join(sorted(missing_plugins))}"
|
||||
)
|
||||
|
||||
|
||||
def find_plugins(
|
||||
cfg: configparser.RawConfigParser,
|
||||
opts: PluginOptions,
|
||||
) -> list[Plugin]:
|
||||
"""Discovers all plugins (but does not load them)."""
|
||||
ret = [*_find_importlib_plugins(), *_find_local_plugins(cfg)]
|
||||
|
||||
# for determinism, sort the list
|
||||
ret.sort()
|
||||
|
||||
_check_required_plugins(ret, opts.require_plugins)
|
||||
|
||||
return ret
|
||||
|
||||
|
||||
def _parameters_for(func: Any) -> dict[str, bool]:
|
||||
"""Return the parameters for the plugin.
|
||||
|
||||
This will inspect the plugin and return either the function parameters
|
||||
if the plugin is a function or the parameters for ``__init__`` after
|
||||
``self`` if the plugin is a class.
|
||||
|
||||
:returns:
|
||||
A dictionary mapping the parameter name to whether or not it is
|
||||
required (a.k.a., is positional only/does not have a default).
|
||||
"""
|
||||
is_class = not inspect.isfunction(func)
|
||||
if is_class:
|
||||
func = func.__init__
|
||||
|
||||
parameters = {
|
||||
parameter.name: parameter.default is inspect.Parameter.empty
|
||||
for parameter in inspect.signature(func).parameters.values()
|
||||
if parameter.kind is inspect.Parameter.POSITIONAL_OR_KEYWORD
|
||||
}
|
||||
|
||||
if is_class:
|
||||
parameters.pop("self", None)
|
||||
|
||||
return parameters
|
||||
|
||||
|
||||
def _load_plugin(plugin: Plugin) -> LoadedPlugin:
|
||||
try:
|
||||
obj = plugin.entry_point.load()
|
||||
except Exception as e:
|
||||
raise FailedToLoadPlugin(plugin.package, e)
|
||||
|
||||
if not callable(obj):
|
||||
err = TypeError("expected loaded plugin to be callable")
|
||||
raise FailedToLoadPlugin(plugin.package, err)
|
||||
|
||||
return LoadedPlugin(plugin, obj, _parameters_for(obj))
|
||||
|
||||
|
||||
def _import_plugins(
|
||||
plugins: list[Plugin],
|
||||
opts: PluginOptions,
|
||||
) -> list[LoadedPlugin]:
|
||||
sys.path.extend(opts.local_plugin_paths)
|
||||
return [_load_plugin(p) for p in plugins]
|
||||
|
||||
|
||||
def _classify_plugins(
|
||||
plugins: list[LoadedPlugin],
|
||||
opts: PluginOptions,
|
||||
) -> Plugins:
|
||||
tree = []
|
||||
logical_line = []
|
||||
physical_line = []
|
||||
reporters = {}
|
||||
disabled = []
|
||||
|
||||
for loaded in plugins:
|
||||
if (
|
||||
getattr(loaded.obj, "off_by_default", False)
|
||||
and loaded.plugin.entry_point.name not in opts.enable_extensions
|
||||
):
|
||||
disabled.append(loaded)
|
||||
elif loaded.plugin.entry_point.group == "flake8.report":
|
||||
reporters[loaded.entry_name] = loaded
|
||||
elif "tree" in loaded.parameters:
|
||||
tree.append(loaded)
|
||||
elif "logical_line" in loaded.parameters:
|
||||
logical_line.append(loaded)
|
||||
elif "physical_line" in loaded.parameters:
|
||||
physical_line.append(loaded)
|
||||
else:
|
||||
raise NotImplementedError(f"what plugin type? {loaded}")
|
||||
|
||||
for loaded in itertools.chain(tree, logical_line, physical_line):
|
||||
if not VALID_CODE_PREFIX.match(loaded.entry_name):
|
||||
raise ExecutionError(
|
||||
f"plugin code for `{loaded.display_name}` does not match "
|
||||
f"{VALID_CODE_PREFIX.pattern}"
|
||||
)
|
||||
|
||||
return Plugins(
|
||||
checkers=Checkers(
|
||||
tree=tree,
|
||||
logical_line=logical_line,
|
||||
physical_line=physical_line,
|
||||
),
|
||||
reporters=reporters,
|
||||
disabled=disabled,
|
||||
)
|
||||
|
||||
|
||||
def load_plugins(
|
||||
plugins: list[Plugin],
|
||||
opts: PluginOptions,
|
||||
) -> 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, opts), opts)
|
||||
112
.venv/lib/python3.12/site-packages/flake8/plugins/pycodestyle.py
Normal file
112
.venv/lib/python3.12/site-packages/flake8/plugins/pycodestyle.py
Normal file
@@ -0,0 +1,112 @@
|
||||
"""Generated using ./bin/gen-pycodestyle-plugin."""
|
||||
# fmt: off
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Any
|
||||
from typing import Generator
|
||||
|
||||
from pycodestyle import ambiguous_identifier as _ambiguous_identifier
|
||||
from pycodestyle import bare_except as _bare_except
|
||||
from pycodestyle import blank_lines as _blank_lines
|
||||
from pycodestyle import break_after_binary_operator as _break_after_binary_operator # noqa: E501
|
||||
from pycodestyle import break_before_binary_operator as _break_before_binary_operator # noqa: E501
|
||||
from pycodestyle import comparison_negative as _comparison_negative
|
||||
from pycodestyle import comparison_to_singleton as _comparison_to_singleton
|
||||
from pycodestyle import comparison_type as _comparison_type
|
||||
from pycodestyle import compound_statements as _compound_statements
|
||||
from pycodestyle import continued_indentation as _continued_indentation
|
||||
from pycodestyle import explicit_line_join as _explicit_line_join
|
||||
from pycodestyle import extraneous_whitespace as _extraneous_whitespace
|
||||
from pycodestyle import imports_on_separate_lines as _imports_on_separate_lines
|
||||
from pycodestyle import indentation as _indentation
|
||||
from pycodestyle import maximum_doc_length as _maximum_doc_length
|
||||
from pycodestyle import maximum_line_length as _maximum_line_length
|
||||
from pycodestyle import missing_whitespace as _missing_whitespace
|
||||
from pycodestyle import missing_whitespace_after_keyword as _missing_whitespace_after_keyword # noqa: E501
|
||||
from pycodestyle import module_imports_on_top_of_file as _module_imports_on_top_of_file # noqa: E501
|
||||
from pycodestyle import python_3000_invalid_escape_sequence as _python_3000_invalid_escape_sequence # noqa: E501
|
||||
from pycodestyle import tabs_obsolete as _tabs_obsolete
|
||||
from pycodestyle import tabs_or_spaces as _tabs_or_spaces
|
||||
from pycodestyle import trailing_blank_lines as _trailing_blank_lines
|
||||
from pycodestyle import trailing_whitespace as _trailing_whitespace
|
||||
from pycodestyle import whitespace_around_comma as _whitespace_around_comma
|
||||
from pycodestyle import whitespace_around_keywords as _whitespace_around_keywords # noqa: E501
|
||||
from pycodestyle import whitespace_around_named_parameter_equals as _whitespace_around_named_parameter_equals # noqa: E501
|
||||
from pycodestyle import whitespace_around_operator as _whitespace_around_operator # noqa: E501
|
||||
from pycodestyle import whitespace_before_comment as _whitespace_before_comment
|
||||
from pycodestyle import whitespace_before_parameters as _whitespace_before_parameters # noqa: E501
|
||||
|
||||
|
||||
def pycodestyle_logical(
|
||||
blank_before: Any,
|
||||
blank_lines: Any,
|
||||
checker_state: Any,
|
||||
hang_closing: Any,
|
||||
indent_char: Any,
|
||||
indent_level: Any,
|
||||
indent_size: Any,
|
||||
line_number: Any,
|
||||
lines: Any,
|
||||
logical_line: Any,
|
||||
max_doc_length: Any,
|
||||
noqa: Any,
|
||||
previous_indent_level: Any,
|
||||
previous_logical: Any,
|
||||
previous_unindented_logical_line: Any,
|
||||
tokens: Any,
|
||||
verbose: Any,
|
||||
) -> Generator[tuple[int, str], None, None]:
|
||||
"""Run pycodestyle logical checks."""
|
||||
yield from _ambiguous_identifier(logical_line, tokens)
|
||||
yield from _bare_except(logical_line, noqa)
|
||||
yield from _blank_lines(logical_line, blank_lines, indent_level, line_number, blank_before, previous_logical, previous_unindented_logical_line, previous_indent_level, lines) # noqa: E501
|
||||
yield from _break_after_binary_operator(logical_line, tokens)
|
||||
yield from _break_before_binary_operator(logical_line, tokens)
|
||||
yield from _comparison_negative(logical_line)
|
||||
yield from _comparison_to_singleton(logical_line, noqa)
|
||||
yield from _comparison_type(logical_line, noqa)
|
||||
yield from _compound_statements(logical_line)
|
||||
yield from _continued_indentation(logical_line, tokens, indent_level, hang_closing, indent_char, indent_size, noqa, verbose) # noqa: E501
|
||||
yield from _explicit_line_join(logical_line, tokens)
|
||||
yield from _extraneous_whitespace(logical_line)
|
||||
yield from _imports_on_separate_lines(logical_line)
|
||||
yield from _indentation(logical_line, previous_logical, indent_char, indent_level, previous_indent_level, indent_size) # noqa: E501
|
||||
yield from _maximum_doc_length(logical_line, max_doc_length, noqa, tokens)
|
||||
yield from _missing_whitespace(logical_line, tokens)
|
||||
yield from _missing_whitespace_after_keyword(logical_line, tokens)
|
||||
yield from _module_imports_on_top_of_file(logical_line, indent_level, checker_state, noqa) # noqa: E501
|
||||
yield from _python_3000_invalid_escape_sequence(logical_line, tokens, noqa)
|
||||
yield from _whitespace_around_comma(logical_line)
|
||||
yield from _whitespace_around_keywords(logical_line)
|
||||
yield from _whitespace_around_named_parameter_equals(logical_line, tokens)
|
||||
yield from _whitespace_around_operator(logical_line)
|
||||
yield from _whitespace_before_comment(logical_line, tokens)
|
||||
yield from _whitespace_before_parameters(logical_line, tokens)
|
||||
|
||||
|
||||
def pycodestyle_physical(
|
||||
indent_char: Any,
|
||||
line_number: Any,
|
||||
lines: Any,
|
||||
max_line_length: Any,
|
||||
multiline: Any,
|
||||
noqa: Any,
|
||||
physical_line: Any,
|
||||
total_lines: Any,
|
||||
) -> Generator[tuple[int, str], None, None]:
|
||||
"""Run pycodestyle physical checks."""
|
||||
ret = _maximum_line_length(physical_line, max_line_length, multiline, line_number, noqa) # noqa: E501
|
||||
if ret is not None:
|
||||
yield ret
|
||||
ret = _tabs_obsolete(physical_line)
|
||||
if ret is not None:
|
||||
yield ret
|
||||
ret = _tabs_or_spaces(physical_line, indent_char)
|
||||
if ret is not None:
|
||||
yield ret
|
||||
ret = _trailing_blank_lines(physical_line, lines, line_number, total_lines)
|
||||
if ret is not None:
|
||||
yield ret
|
||||
ret = _trailing_whitespace(physical_line)
|
||||
if ret is not None:
|
||||
yield ret
|
||||
112
.venv/lib/python3.12/site-packages/flake8/plugins/pyflakes.py
Normal file
112
.venv/lib/python3.12/site-packages/flake8/plugins/pyflakes.py
Normal file
@@ -0,0 +1,112 @@
|
||||
"""Plugin built-in to Flake8 to treat pyflakes as a plugin."""
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import ast
|
||||
import logging
|
||||
from typing import Any
|
||||
from typing import Generator
|
||||
|
||||
import pyflakes.checker
|
||||
|
||||
from flake8.options.manager import OptionManager
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
FLAKE8_PYFLAKES_CODES = {
|
||||
"UnusedImport": "F401",
|
||||
"ImportShadowedByLoopVar": "F402",
|
||||
"ImportStarUsed": "F403",
|
||||
"LateFutureImport": "F404",
|
||||
"ImportStarUsage": "F405",
|
||||
"ImportStarNotPermitted": "F406",
|
||||
"FutureFeatureNotDefined": "F407",
|
||||
"PercentFormatInvalidFormat": "F501",
|
||||
"PercentFormatExpectedMapping": "F502",
|
||||
"PercentFormatExpectedSequence": "F503",
|
||||
"PercentFormatExtraNamedArguments": "F504",
|
||||
"PercentFormatMissingArgument": "F505",
|
||||
"PercentFormatMixedPositionalAndNamed": "F506",
|
||||
"PercentFormatPositionalCountMismatch": "F507",
|
||||
"PercentFormatStarRequiresSequence": "F508",
|
||||
"PercentFormatUnsupportedFormatCharacter": "F509",
|
||||
"StringDotFormatInvalidFormat": "F521",
|
||||
"StringDotFormatExtraNamedArguments": "F522",
|
||||
"StringDotFormatExtraPositionalArguments": "F523",
|
||||
"StringDotFormatMissingArgument": "F524",
|
||||
"StringDotFormatMixingAutomatic": "F525",
|
||||
"FStringMissingPlaceholders": "F541",
|
||||
"MultiValueRepeatedKeyLiteral": "F601",
|
||||
"MultiValueRepeatedKeyVariable": "F602",
|
||||
"TooManyExpressionsInStarredAssignment": "F621",
|
||||
"TwoStarredExpressions": "F622",
|
||||
"AssertTuple": "F631",
|
||||
"IsLiteral": "F632",
|
||||
"InvalidPrintSyntax": "F633",
|
||||
"IfTuple": "F634",
|
||||
"BreakOutsideLoop": "F701",
|
||||
"ContinueOutsideLoop": "F702",
|
||||
"YieldOutsideFunction": "F704",
|
||||
"ReturnOutsideFunction": "F706",
|
||||
"DefaultExceptNotLast": "F707",
|
||||
"DoctestSyntaxError": "F721",
|
||||
"ForwardAnnotationSyntaxError": "F722",
|
||||
"RedefinedWhileUnused": "F811",
|
||||
"UndefinedName": "F821",
|
||||
"UndefinedExport": "F822",
|
||||
"UndefinedLocal": "F823",
|
||||
"DuplicateArgument": "F831",
|
||||
"UnusedVariable": "F841",
|
||||
"UnusedAnnotation": "F842",
|
||||
"RaiseNotImplemented": "F901",
|
||||
}
|
||||
|
||||
|
||||
class FlakesChecker(pyflakes.checker.Checker):
|
||||
"""Subclass the Pyflakes checker to conform with the flake8 API."""
|
||||
|
||||
with_doctest = False
|
||||
|
||||
def __init__(self, tree: ast.AST, filename: str) -> None:
|
||||
"""Initialize the PyFlakes plugin with an AST tree and filename."""
|
||||
super().__init__(
|
||||
tree, filename=filename, withDoctest=self.with_doctest
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def add_options(cls, parser: OptionManager) -> None:
|
||||
"""Register options for PyFlakes on the Flake8 OptionManager."""
|
||||
parser.add_option(
|
||||
"--builtins",
|
||||
parse_from_config=True,
|
||||
comma_separated_list=True,
|
||||
help="define more built-ins, comma separated",
|
||||
)
|
||||
parser.add_option(
|
||||
"--doctests",
|
||||
default=False,
|
||||
action="store_true",
|
||||
parse_from_config=True,
|
||||
help="also check syntax of the doctests",
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def parse_options(cls, options: argparse.Namespace) -> None:
|
||||
"""Parse option values from Flake8's OptionManager."""
|
||||
if options.builtins:
|
||||
cls.builtIns = cls.builtIns.union(options.builtins)
|
||||
cls.with_doctest = options.doctests
|
||||
|
||||
def run(self) -> Generator[tuple[int, int, str, type[Any]], None, None]:
|
||||
"""Run the plugin."""
|
||||
for message in self.messages:
|
||||
col = getattr(message, "col", 0)
|
||||
yield (
|
||||
message.lineno,
|
||||
col,
|
||||
"{} {}".format(
|
||||
FLAKE8_PYFLAKES_CODES.get(type(message).__name__, "F999"),
|
||||
message.message % message.message_args,
|
||||
),
|
||||
message.__class__,
|
||||
)
|
||||
@@ -0,0 +1,42 @@
|
||||
"""Functions for constructing the requested report plugin."""
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import logging
|
||||
|
||||
from flake8.formatting.base import BaseFormatter
|
||||
from flake8.plugins.finder import LoadedPlugin
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def make(
|
||||
reporters: dict[str, LoadedPlugin],
|
||||
options: argparse.Namespace,
|
||||
) -> BaseFormatter:
|
||||
"""Make the formatter from the requested user options.
|
||||
|
||||
- if :option:`flake8 --quiet` is specified, return the ``quiet-filename``
|
||||
formatter.
|
||||
- if :option:`flake8 --quiet` is specified at least twice, return the
|
||||
``quiet-nothing`` formatter.
|
||||
- otherwise attempt to return the formatter by name.
|
||||
- failing that, assume it is a format string and return the ``default``
|
||||
formatter.
|
||||
"""
|
||||
format_name = options.format
|
||||
if options.quiet == 1:
|
||||
format_name = "quiet-filename"
|
||||
elif options.quiet >= 2:
|
||||
format_name = "quiet-nothing"
|
||||
|
||||
try:
|
||||
format_plugin = reporters[format_name]
|
||||
except KeyError:
|
||||
LOG.warning(
|
||||
"%r is an unknown formatter. Falling back to default.",
|
||||
format_name,
|
||||
)
|
||||
format_plugin = reporters["default"]
|
||||
|
||||
return format_plugin.obj(options)
|
||||
Reference in New Issue
Block a user