mirror of
https://github.com/PyCQA/flake8.git
synced 2026-03-29 10:36:53 +00:00
commit
a929f124c8
76 changed files with 337 additions and 263 deletions
5
.github/workflows/main.yml
vendored
5
.github/workflows/main.yml
vendored
|
|
@ -15,9 +15,6 @@ jobs:
|
|||
- os: ubuntu-latest
|
||||
python: pypy-3.7
|
||||
toxenv: py
|
||||
- os: ubuntu-latest
|
||||
python: 3.6
|
||||
toxenv: py
|
||||
- os: ubuntu-latest
|
||||
python: 3.7
|
||||
toxenv: py
|
||||
|
|
@ -32,7 +29,7 @@ jobs:
|
|||
toxenv: py
|
||||
# windows
|
||||
- os: windows-latest
|
||||
python: 3.6
|
||||
python: 3.7
|
||||
toxenv: py
|
||||
# misc
|
||||
- os: ubuntu-latest
|
||||
|
|
|
|||
|
|
@ -11,12 +11,16 @@ repos:
|
|||
rev: v3.8.2
|
||||
hooks:
|
||||
- id: reorder-python-imports
|
||||
args: [--application-directories, '.:src', --py36-plus]
|
||||
args: [
|
||||
--application-directories, '.:src',
|
||||
--py37-plus,
|
||||
--add-import, 'from __future__ import annotations',
|
||||
]
|
||||
- repo: https://github.com/asottile/pyupgrade
|
||||
rev: v2.37.3
|
||||
hooks:
|
||||
- id: pyupgrade
|
||||
args: [--py36-plus]
|
||||
args: [--py37-plus]
|
||||
- repo: https://github.com/psf/black
|
||||
rev: 22.6.0
|
||||
hooks:
|
||||
|
|
|
|||
|
|
@ -1,11 +1,12 @@
|
|||
#!/usr/bin/env python3
|
||||
from __future__ import annotations
|
||||
|
||||
import inspect
|
||||
import os.path
|
||||
from typing import Any
|
||||
from typing import Callable
|
||||
from typing import Generator
|
||||
from typing import NamedTuple
|
||||
from typing import Tuple
|
||||
|
||||
import pycodestyle
|
||||
|
||||
|
|
@ -20,7 +21,7 @@ def _too_long(s: str) -> str:
|
|||
class Call(NamedTuple):
|
||||
name: str
|
||||
is_generator: bool
|
||||
params: Tuple[str, ...]
|
||||
params: tuple[str, ...]
|
||||
|
||||
def to_src(self) -> str:
|
||||
params_s = ", ".join(self.params)
|
||||
|
|
@ -35,7 +36,7 @@ class Call(NamedTuple):
|
|||
return "\n".join(lines)
|
||||
|
||||
@classmethod
|
||||
def from_func(cls, func: Callable[..., Any]) -> "Call":
|
||||
def from_func(cls, func: Callable[..., Any]) -> Call:
|
||||
spec = inspect.getfullargspec(func)
|
||||
params = tuple(spec.args)
|
||||
return cls(func.__name__, inspect.isgeneratorfunction(func), params)
|
||||
|
|
@ -55,9 +56,10 @@ def lines() -> Generator[str, None, None]:
|
|||
|
||||
yield f'"""Generated using ./bin/{os.path.basename(__file__)}."""'
|
||||
yield "# fmt: off"
|
||||
yield "from __future__ import annotations"
|
||||
yield ""
|
||||
yield "from typing import Any"
|
||||
yield "from typing import Generator"
|
||||
yield "from typing import Tuple"
|
||||
yield ""
|
||||
imports = sorted(call.name for call in logical + physical)
|
||||
for name in imports:
|
||||
|
|
@ -69,7 +71,7 @@ def lines() -> Generator[str, None, None]:
|
|||
logical_params = {param for call in logical for param in call.params}
|
||||
for param in sorted(logical_params):
|
||||
yield f" {param}: Any,"
|
||||
yield ") -> Generator[Tuple[int, str], None, None]:"
|
||||
yield ") -> Generator[tuple[int, str], None, None]:"
|
||||
yield ' """Run pycodestyle logical checks."""'
|
||||
for call in sorted(logical):
|
||||
yield call.to_src()
|
||||
|
|
@ -80,7 +82,7 @@ def lines() -> Generator[str, None, None]:
|
|||
physical_params = {param for call in physical for param in call.params}
|
||||
for param in sorted(physical_params):
|
||||
yield f" {param}: Any,"
|
||||
yield ") -> Generator[Tuple[int, str], None, None]:"
|
||||
yield ") -> Generator[tuple[int, str], None, None]:"
|
||||
yield ' """Run pycodestyle physical checks."""'
|
||||
for call in sorted(physical):
|
||||
yield call.to_src()
|
||||
|
|
|
|||
|
|
@ -14,6 +14,8 @@
|
|||
# add these directories to sys.path here. If the directory is relative to the
|
||||
# documentation root, use os.path.abspath to make it absolute, like shown here.
|
||||
# sys.path.insert(0, os.path.abspath('.'))
|
||||
from __future__ import annotations
|
||||
|
||||
import flake8
|
||||
|
||||
# -- General configuration ------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
from __future__ import annotations
|
||||
|
||||
import setuptools
|
||||
|
||||
setuptools.setup(
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
"""Module for an example Flake8 plugin."""
|
||||
from __future__ import annotations
|
||||
|
||||
from .off_by_default import ExampleTwo
|
||||
from .on_by_default import ExampleOne
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
"""Our first example plugin."""
|
||||
from __future__ import annotations
|
||||
|
||||
|
||||
class ExampleTwo:
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
"""Our first example plugin."""
|
||||
from __future__ import annotations
|
||||
|
||||
|
||||
class ExampleOne:
|
||||
|
|
|
|||
|
|
@ -20,7 +20,6 @@ classifiers =
|
|||
Programming Language :: Python
|
||||
Programming Language :: Python :: 3
|
||||
Programming Language :: Python :: 3 :: Only
|
||||
Programming Language :: Python :: 3.6
|
||||
Programming Language :: Python :: 3.7
|
||||
Programming Language :: Python :: 3.8
|
||||
Programming Language :: Python :: 3.9
|
||||
|
|
@ -43,7 +42,7 @@ install_requires =
|
|||
pycodestyle>=2.9.0,<2.10.0
|
||||
pyflakes>=2.5.0,<2.6.0
|
||||
importlib-metadata>=1.1.0,<4.3;python_version<"3.8"
|
||||
python_requires = >=3.6.1
|
||||
python_requires = >=3.7
|
||||
|
||||
[options.packages.find]
|
||||
where = src
|
||||
|
|
|
|||
2
setup.py
2
setup.py
|
|
@ -1,4 +1,6 @@
|
|||
"""Packaging logic for Flake8."""
|
||||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
|
|
|
|||
|
|
@ -9,10 +9,10 @@ This module
|
|||
.. autofunction:: flake8.configure_logging
|
||||
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import logging
|
||||
import sys
|
||||
from typing import Optional
|
||||
from typing import Type
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
LOG.addHandler(logging.NullHandler())
|
||||
|
|
@ -35,7 +35,7 @@ LOG_FORMAT = (
|
|||
|
||||
def configure_logging(
|
||||
verbosity: int,
|
||||
filename: Optional[str] = None,
|
||||
filename: str | None = None,
|
||||
logformat: str = LOG_FORMAT,
|
||||
) -> None:
|
||||
"""Configure logging for flake8.
|
||||
|
|
@ -56,7 +56,7 @@ def configure_logging(
|
|||
|
||||
if not filename or filename in ("stderr", "stdout"):
|
||||
fileobj = getattr(sys, filename or "stderr")
|
||||
handler_cls: Type[logging.Handler] = logging.StreamHandler
|
||||
handler_cls: type[logging.Handler] = logging.StreamHandler
|
||||
else:
|
||||
fileobj = filename
|
||||
handler_cls = logging.FileHandler
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
"""Module allowing for ``python -m flake8 ...``."""
|
||||
from __future__ import annotations
|
||||
|
||||
from flake8.main.cli import main
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
"""Expose backports in a single place."""
|
||||
from __future__ import annotations
|
||||
|
||||
import sys
|
||||
|
||||
if sys.version_info >= (3, 8): # pragma: no cover (PY38+)
|
||||
|
|
|
|||
|
|
@ -3,3 +3,4 @@
|
|||
This is the only submodule in Flake8 with a guaranteed stable API. All other
|
||||
submodules are considered internal only and are subject to change.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
|
|
|||
|
|
@ -3,13 +3,12 @@
|
|||
Previously, users would import :func:`get_style_guide` from ``flake8.engine``.
|
||||
In 3.0 we no longer have an "engine" module but we maintain the API from it.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import logging
|
||||
import os.path
|
||||
from typing import Any
|
||||
from typing import List
|
||||
from typing import Optional
|
||||
from typing import Type
|
||||
|
||||
import flake8
|
||||
from flake8.discover_files import expand_paths
|
||||
|
|
@ -53,7 +52,7 @@ class Report:
|
|||
"""Return the total number of errors."""
|
||||
return self._application.result_count
|
||||
|
||||
def get_statistics(self, violation: str) -> List[str]:
|
||||
def get_statistics(self, violation: str) -> list[str]:
|
||||
"""Get the list of occurrences of a violation.
|
||||
|
||||
:returns:
|
||||
|
|
@ -97,12 +96,12 @@ class StyleGuide:
|
|||
return self._application.options
|
||||
|
||||
@property
|
||||
def paths(self) -> List[str]:
|
||||
def paths(self) -> list[str]:
|
||||
"""Return the extra arguments passed as paths."""
|
||||
assert self._application.options is not None
|
||||
return self._application.options.filenames
|
||||
|
||||
def check_files(self, paths: Optional[List[str]] = None) -> Report:
|
||||
def check_files(self, paths: list[str] | None = None) -> Report:
|
||||
"""Run collected checks on the files provided.
|
||||
|
||||
This will check the files passed in and return a :class:`Report`
|
||||
|
|
@ -119,7 +118,7 @@ class StyleGuide:
|
|||
self._application.report_errors()
|
||||
return Report(self._application)
|
||||
|
||||
def excluded(self, filename: str, parent: Optional[str] = None) -> bool:
|
||||
def excluded(self, filename: str, parent: str | None = None) -> bool:
|
||||
"""Determine if a file is excluded.
|
||||
|
||||
:param filename:
|
||||
|
|
@ -148,7 +147,7 @@ class StyleGuide:
|
|||
|
||||
def init_report(
|
||||
self,
|
||||
reporter: Optional[Type[formatter.BaseFormatter]] = None,
|
||||
reporter: type[formatter.BaseFormatter] | None = None,
|
||||
) -> None:
|
||||
"""Set up a formatter for this run of Flake8."""
|
||||
if reporter is None:
|
||||
|
|
@ -170,9 +169,9 @@ class StyleGuide:
|
|||
def input_file(
|
||||
self,
|
||||
filename: str,
|
||||
lines: Optional[Any] = None,
|
||||
expected: Optional[Any] = None,
|
||||
line_offset: Optional[Any] = 0,
|
||||
lines: Any | None = None,
|
||||
expected: Any | None = None,
|
||||
line_offset: Any | None = 0,
|
||||
) -> Report:
|
||||
"""Run collected checks on a single file.
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
"""Checker Manager and Checker classes."""
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import collections
|
||||
import errno
|
||||
|
|
@ -8,7 +10,6 @@ import multiprocessing.pool
|
|||
import signal
|
||||
import tokenize
|
||||
from typing import Any
|
||||
from typing import Dict
|
||||
from typing import List
|
||||
from typing import Optional
|
||||
from typing import Tuple
|
||||
|
|
@ -71,8 +72,8 @@ class Manager:
|
|||
self.options = style_guide.options
|
||||
self.plugins = plugins
|
||||
self.jobs = self._job_count()
|
||||
self._all_checkers: List[FileChecker] = []
|
||||
self.checkers: List[FileChecker] = []
|
||||
self._all_checkers: list[FileChecker] = []
|
||||
self.checkers: list[FileChecker] = []
|
||||
self.statistics = {
|
||||
"files": 0,
|
||||
"logical lines": 0,
|
||||
|
|
@ -152,7 +153,7 @@ class Manager:
|
|||
)
|
||||
return reported_results_count
|
||||
|
||||
def make_checkers(self, paths: Optional[List[str]] = None) -> None:
|
||||
def make_checkers(self, paths: list[str] | None = None) -> None:
|
||||
"""Create checkers for each file."""
|
||||
if paths is None:
|
||||
paths = self.options.filenames
|
||||
|
|
@ -174,7 +175,7 @@ class Manager:
|
|||
self.checkers = [c for c in self._all_checkers if c.should_process]
|
||||
LOG.info("Checking %d files", len(self.checkers))
|
||||
|
||||
def report(self) -> Tuple[int, int]:
|
||||
def report(self) -> tuple[int, int]:
|
||||
"""Report all of the errors found in the managed file checkers.
|
||||
|
||||
This iterates over each of the checkers and reports the errors sorted
|
||||
|
|
@ -195,8 +196,8 @@ class Manager:
|
|||
def run_parallel(self) -> None:
|
||||
"""Run the checkers in parallel."""
|
||||
# fmt: off
|
||||
final_results: Dict[str, List[Tuple[str, int, int, str, Optional[str]]]] = collections.defaultdict(list) # noqa: E501
|
||||
final_statistics: Dict[str, Dict[str, int]] = collections.defaultdict(dict) # noqa: E501
|
||||
final_results: dict[str, list[tuple[str, int, int, str, str | None]]] = collections.defaultdict(list) # noqa: E501
|
||||
final_statistics: dict[str, dict[str, int]] = collections.defaultdict(dict) # noqa: E501
|
||||
# fmt: on
|
||||
|
||||
pool = _try_initialize_processpool(self.jobs)
|
||||
|
|
@ -254,7 +255,7 @@ class Manager:
|
|||
LOG.warning("Flake8 was interrupted by the user")
|
||||
raise exceptions.EarlyQuit("Early quit while running checks")
|
||||
|
||||
def start(self, paths: Optional[List[str]] = None) -> None:
|
||||
def start(self, paths: list[str] | None = None) -> None:
|
||||
"""Start checking files.
|
||||
|
||||
:param paths:
|
||||
|
|
@ -301,7 +302,7 @@ class FileChecker:
|
|||
"""Provide helpful debugging representation."""
|
||||
return f"FileChecker for {self.filename}"
|
||||
|
||||
def _make_processor(self) -> Optional[processor.FileProcessor]:
|
||||
def _make_processor(self) -> processor.FileProcessor | None:
|
||||
try:
|
||||
return processor.FileProcessor(self.filename, self.options)
|
||||
except OSError as e:
|
||||
|
|
@ -316,7 +317,7 @@ class FileChecker:
|
|||
|
||||
def report(
|
||||
self,
|
||||
error_code: Optional[str],
|
||||
error_code: str | None,
|
||||
line_number: int,
|
||||
column: int,
|
||||
text: str,
|
||||
|
|
@ -361,7 +362,7 @@ class FileChecker:
|
|||
)
|
||||
|
||||
@staticmethod
|
||||
def _extract_syntax_information(exception: Exception) -> Tuple[int, int]:
|
||||
def _extract_syntax_information(exception: Exception) -> tuple[int, int]:
|
||||
if (
|
||||
len(exception.args) > 1
|
||||
and exception.args[1]
|
||||
|
|
@ -524,7 +525,7 @@ class FileChecker:
|
|||
self.run_physical_checks(file_processor.lines[-1])
|
||||
self.run_logical_checks()
|
||||
|
||||
def run_checks(self) -> Tuple[str, Results, Dict[str, int]]:
|
||||
def run_checks(self) -> tuple[str, Results, dict[str, int]]:
|
||||
"""Run checks against the file."""
|
||||
assert self.processor is not None
|
||||
try:
|
||||
|
|
@ -592,7 +593,7 @@ def _pool_init() -> None:
|
|||
|
||||
def _try_initialize_processpool(
|
||||
job_count: int,
|
||||
) -> Optional[multiprocessing.pool.Pool]:
|
||||
) -> multiprocessing.pool.Pool | None:
|
||||
"""Return a new process pool instance if we are able to create one."""
|
||||
try:
|
||||
return multiprocessing.Pool(job_count, _pool_init)
|
||||
|
|
@ -617,13 +618,13 @@ def calculate_pool_chunksize(num_checkers: int, num_jobs: int) -> int:
|
|||
return max(num_checkers // (num_jobs * 2), 1)
|
||||
|
||||
|
||||
def _run_checks(checker: FileChecker) -> Tuple[str, Results, Dict[str, int]]:
|
||||
def _run_checks(checker: FileChecker) -> tuple[str, Results, dict[str, int]]:
|
||||
return checker.run_checks()
|
||||
|
||||
|
||||
def find_offset(
|
||||
offset: int, mapping: processor._LogicalMapping
|
||||
) -> Tuple[int, int]:
|
||||
) -> tuple[int, int]:
|
||||
"""Find the offset tuple for a single offset."""
|
||||
if isinstance(offset, tuple):
|
||||
return offset
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
"""Constants that define defaults."""
|
||||
from __future__ import annotations
|
||||
|
||||
import re
|
||||
|
||||
EXCLUDE = (
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
"""Functions related to discovering paths."""
|
||||
from __future__ import annotations
|
||||
|
||||
import logging
|
||||
import os.path
|
||||
from typing import Callable
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
"""Exception classes for all of Flake8."""
|
||||
from __future__ import annotations
|
||||
|
||||
|
||||
class Flake8Exception(Exception):
|
||||
|
|
|
|||
|
|
@ -1 +1,2 @@
|
|||
"""Submodule containing the default formatters for Flake8."""
|
||||
from __future__ import annotations
|
||||
|
|
|
|||
|
|
@ -2,6 +2,8 @@
|
|||
|
||||
See: https://github.com/pre-commit/pre-commit/blob/cb40e96/pre_commit/color.py
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import sys
|
||||
|
||||
if sys.platform == "win32": # pragma: no cover (windows)
|
||||
|
|
|
|||
|
|
@ -1,11 +1,10 @@
|
|||
"""The base class and interface for all formatting plugins."""
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import os
|
||||
import sys
|
||||
from typing import IO
|
||||
from typing import List
|
||||
from typing import Optional
|
||||
from typing import Tuple
|
||||
|
||||
from flake8.formatting import _windows_color
|
||||
from flake8.statistics import Statistics
|
||||
|
|
@ -46,7 +45,7 @@ class BaseFormatter:
|
|||
"""
|
||||
self.options = options
|
||||
self.filename = options.output_file
|
||||
self.output_fd: Optional[IO[str]] = None
|
||||
self.output_fd: IO[str] | None = None
|
||||
self.newline = "\n"
|
||||
self.color = options.color == "always" or (
|
||||
options.color == "auto"
|
||||
|
|
@ -84,7 +83,7 @@ class BaseFormatter:
|
|||
os.makedirs(dirname, exist_ok=True)
|
||||
self.output_fd = open(self.filename, "a")
|
||||
|
||||
def handle(self, error: "Violation") -> None:
|
||||
def handle(self, error: Violation) -> None:
|
||||
"""Handle an error reported by Flake8.
|
||||
|
||||
This defaults to calling :meth:`format`, :meth:`show_source`, and
|
||||
|
|
@ -99,7 +98,7 @@ class BaseFormatter:
|
|||
source = self.show_source(error)
|
||||
self.write(line, source)
|
||||
|
||||
def format(self, error: "Violation") -> Optional[str]:
|
||||
def format(self, error: Violation) -> str | None:
|
||||
"""Format an error reported by Flake8.
|
||||
|
||||
This method **must** be implemented by subclasses.
|
||||
|
|
@ -114,7 +113,7 @@ class BaseFormatter:
|
|||
"Subclass of BaseFormatter did not implement" " format."
|
||||
)
|
||||
|
||||
def show_statistics(self, statistics: "Statistics") -> None:
|
||||
def show_statistics(self, statistics: Statistics) -> None:
|
||||
"""Format and print the statistics."""
|
||||
for error_code in statistics.error_codes():
|
||||
stats_for_error_code = statistics.statistics_for(error_code)
|
||||
|
|
@ -123,7 +122,7 @@ class BaseFormatter:
|
|||
count += sum(stat.count for stat in stats_for_error_code)
|
||||
self._write(f"{count:<5} {error_code} {statistic.message}")
|
||||
|
||||
def show_benchmarks(self, benchmarks: List[Tuple[str, float]]) -> None:
|
||||
def show_benchmarks(self, benchmarks: list[tuple[str, float]]) -> None:
|
||||
"""Format and print the benchmarks."""
|
||||
# NOTE(sigmavirus24): The format strings are a little confusing, even
|
||||
# to me, so here's a quick explanation:
|
||||
|
|
@ -144,7 +143,7 @@ class BaseFormatter:
|
|||
benchmark = float_format(statistic=statistic, value=value)
|
||||
self._write(benchmark)
|
||||
|
||||
def show_source(self, error: "Violation") -> Optional[str]:
|
||||
def show_source(self, error: Violation) -> str | None:
|
||||
"""Show the physical line generating the error.
|
||||
|
||||
This also adds an indicator for the particular part of the line that
|
||||
|
|
@ -178,7 +177,7 @@ class BaseFormatter:
|
|||
if self.output_fd is None or self.options.tee:
|
||||
sys.stdout.buffer.write(output.encode() + self.newline.encode())
|
||||
|
||||
def write(self, line: Optional[str], source: Optional[str]) -> None:
|
||||
def write(self, line: str | None, source: str | None) -> None:
|
||||
"""Write the line either to the output file or stdout.
|
||||
|
||||
This handles deciding whether to write to a file or print to standard
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
"""Default formatting class for Flake8."""
|
||||
from typing import Optional
|
||||
from typing import Set
|
||||
from __future__ import annotations
|
||||
|
||||
from flake8.formatting import base
|
||||
from flake8.violation import Violation
|
||||
|
|
@ -38,7 +37,7 @@ class SimpleFormatter(base.BaseFormatter):
|
|||
|
||||
error_format: str
|
||||
|
||||
def format(self, error: "Violation") -> Optional[str]:
|
||||
def format(self, error: Violation) -> str | None:
|
||||
"""Format and write error out.
|
||||
|
||||
If an output filename is specified, write formatted errors to that
|
||||
|
|
@ -86,12 +85,12 @@ class FilenameOnly(SimpleFormatter):
|
|||
|
||||
def after_init(self) -> None:
|
||||
"""Initialize our set of filenames."""
|
||||
self.filenames_already_printed: Set[str] = set()
|
||||
self.filenames_already_printed: set[str] = set()
|
||||
|
||||
def show_source(self, error: "Violation") -> Optional[str]:
|
||||
def show_source(self, error: Violation) -> str | None:
|
||||
"""Do not include the source code."""
|
||||
|
||||
def format(self, error: "Violation") -> Optional[str]:
|
||||
def format(self, error: Violation) -> str | None:
|
||||
"""Ensure we only print each error once."""
|
||||
if error.filename not in self.filenames_already_printed:
|
||||
self.filenames_already_printed.add(error.filename)
|
||||
|
|
@ -103,8 +102,8 @@ class FilenameOnly(SimpleFormatter):
|
|||
class Nothing(base.BaseFormatter):
|
||||
"""Print absolutely nothing."""
|
||||
|
||||
def format(self, error: "Violation") -> Optional[str]:
|
||||
def format(self, error: Violation) -> str | None:
|
||||
"""Do nothing."""
|
||||
|
||||
def show_source(self, error: "Violation") -> Optional[str]:
|
||||
def show_source(self, error: Violation) -> str | None:
|
||||
"""Do not print the source."""
|
||||
|
|
|
|||
|
|
@ -1 +1,2 @@
|
|||
"""Module containing the logic for the Flake8 entry-points."""
|
||||
from __future__ import annotations
|
||||
|
|
|
|||
|
|
@ -1,15 +1,12 @@
|
|||
"""Module containing the application logic for Flake8."""
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import configparser
|
||||
import json
|
||||
import logging
|
||||
import time
|
||||
from typing import Dict
|
||||
from typing import List
|
||||
from typing import Optional
|
||||
from typing import Sequence
|
||||
from typing import Set
|
||||
from typing import Tuple
|
||||
|
||||
import flake8
|
||||
from flake8 import checker
|
||||
|
|
@ -38,27 +35,27 @@ class Application:
|
|||
#: The timestamp when the Application instance was instantiated.
|
||||
self.start_time = time.time()
|
||||
#: The timestamp when the Application finished reported errors.
|
||||
self.end_time: Optional[float] = None
|
||||
self.end_time: float | None = None
|
||||
#: The prelimary argument parser for handling options required for
|
||||
#: obtaining and parsing the configuration file.
|
||||
self.prelim_arg_parser = options.stage1_arg_parser()
|
||||
#: The instance of :class:`flake8.options.manager.OptionManager` used
|
||||
#: to parse and handle the options and arguments passed by the user
|
||||
self.option_manager: Optional[manager.OptionManager] = None
|
||||
self.option_manager: manager.OptionManager | None = None
|
||||
|
||||
self.plugins: Optional[finder.Plugins] = None
|
||||
self.plugins: finder.Plugins | None = None
|
||||
#: The user-selected formatter from :attr:`formatting_plugins`
|
||||
self.formatter: Optional[BaseFormatter] = None
|
||||
self.formatter: BaseFormatter | None = None
|
||||
#: The :class:`flake8.style_guide.StyleGuideManager` built from the
|
||||
#: user's options
|
||||
self.guide: Optional[style_guide.StyleGuideManager] = None
|
||||
self.guide: style_guide.StyleGuideManager | None = None
|
||||
#: The :class:`flake8.checker.Manager` that will handle running all of
|
||||
#: the checks selected by the user.
|
||||
self.file_checker_manager: Optional[checker.Manager] = None
|
||||
self.file_checker_manager: checker.Manager | None = None
|
||||
|
||||
#: The user-supplied options parsed into an instance of
|
||||
#: :class:`argparse.Namespace`
|
||||
self.options: Optional[argparse.Namespace] = None
|
||||
self.options: argparse.Namespace | None = None
|
||||
#: The number of errors, warnings, and other messages after running
|
||||
#: flake8 and taking into account ignored errors and lines.
|
||||
self.result_count = 0
|
||||
|
|
@ -70,11 +67,11 @@ class Application:
|
|||
self.catastrophic_failure = False
|
||||
|
||||
#: The parsed diff information
|
||||
self.parsed_diff: Dict[str, Set[int]] = {}
|
||||
self.parsed_diff: dict[str, set[int]] = {}
|
||||
|
||||
def parse_preliminary_options(
|
||||
self, argv: Sequence[str]
|
||||
) -> Tuple[argparse.Namespace, List[str]]:
|
||||
) -> tuple[argparse.Namespace, list[str]]:
|
||||
"""Get preliminary options from the CLI, pre-plugin-loading.
|
||||
|
||||
We need to know the values of a few standard options so that we can
|
||||
|
|
@ -111,8 +108,8 @@ class Application:
|
|||
cfg: configparser.RawConfigParser,
|
||||
cfg_dir: str,
|
||||
*,
|
||||
enable_extensions: Optional[str],
|
||||
require_plugins: Optional[str],
|
||||
enable_extensions: str | None,
|
||||
require_plugins: str | None,
|
||||
) -> None:
|
||||
"""Find and load the plugins for this application.
|
||||
|
||||
|
|
@ -143,7 +140,7 @@ class Application:
|
|||
self,
|
||||
cfg: configparser.RawConfigParser,
|
||||
cfg_dir: str,
|
||||
argv: List[str],
|
||||
argv: list[str],
|
||||
) -> None:
|
||||
"""Parse configuration files and the CLI options."""
|
||||
assert self.option_manager is not None
|
||||
|
|
@ -218,7 +215,7 @@ class Application:
|
|||
assert self.options is not None
|
||||
assert self.file_checker_manager is not None
|
||||
if self.options.diff:
|
||||
files: Optional[List[str]] = sorted(self.parsed_diff)
|
||||
files: list[str] | None = sorted(self.parsed_diff)
|
||||
if not files:
|
||||
return
|
||||
else:
|
||||
|
|
|
|||
|
|
@ -1,12 +1,13 @@
|
|||
"""Command-line implementation of flake8."""
|
||||
from __future__ import annotations
|
||||
|
||||
import sys
|
||||
from typing import Optional
|
||||
from typing import Sequence
|
||||
|
||||
from flake8.main import application
|
||||
|
||||
|
||||
def main(argv: Optional[Sequence[str]] = None) -> int:
|
||||
def main(argv: Sequence[str] | None = None) -> int:
|
||||
"""Execute the main bit of the application.
|
||||
|
||||
This handles the creation of an instance of :class:`Application`, runs it,
|
||||
|
|
|
|||
|
|
@ -1,12 +1,13 @@
|
|||
"""Module containing the logic for our debugging logic."""
|
||||
from __future__ import annotations
|
||||
|
||||
import platform
|
||||
from typing import Any
|
||||
from typing import Dict
|
||||
|
||||
from flake8.plugins.finder import Plugins
|
||||
|
||||
|
||||
def information(version: str, plugins: Plugins) -> Dict[str, Any]:
|
||||
def information(version: str, plugins: Plugins) -> dict[str, Any]:
|
||||
"""Generate the information to be printed for the bug report."""
|
||||
versions = sorted(
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
"""Contains the logic for all of the default options for Flake8."""
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
|
||||
from flake8 import defaults
|
||||
|
|
|
|||
|
|
@ -10,3 +10,4 @@
|
|||
to aggregate configuration into one object used by plugins and Flake8.
|
||||
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
|
|
|||
|
|
@ -3,10 +3,11 @@
|
|||
This holds the logic that uses the collected and merged config files and
|
||||
applies the user-specified command-line configuration on top of it.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import configparser
|
||||
import logging
|
||||
from typing import Optional
|
||||
from typing import Sequence
|
||||
|
||||
from flake8.options import config
|
||||
|
|
@ -19,7 +20,7 @@ def aggregate_options(
|
|||
manager: OptionManager,
|
||||
cfg: configparser.RawConfigParser,
|
||||
cfg_dir: str,
|
||||
argv: Optional[Sequence[str]],
|
||||
argv: Sequence[str] | None,
|
||||
) -> argparse.Namespace:
|
||||
"""Aggregate and merge CLI and config file options."""
|
||||
# Get defaults from the option parser
|
||||
|
|
|
|||
|
|
@ -1,12 +1,10 @@
|
|||
"""Config handling logic for Flake8."""
|
||||
from __future__ import annotations
|
||||
|
||||
import configparser
|
||||
import logging
|
||||
import os.path
|
||||
from typing import Any
|
||||
from typing import Dict
|
||||
from typing import List
|
||||
from typing import Optional
|
||||
from typing import Tuple
|
||||
|
||||
from flake8 import exceptions
|
||||
from flake8.options.manager import OptionManager
|
||||
|
|
@ -14,13 +12,13 @@ from flake8.options.manager import OptionManager
|
|||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def _stat_key(s: str) -> Tuple[int, int]:
|
||||
def _stat_key(s: str) -> tuple[int, int]:
|
||||
# same as what's used by samefile / samestat
|
||||
st = os.stat(s)
|
||||
return st.st_ino, st.st_dev
|
||||
|
||||
|
||||
def _find_config_file(path: str) -> Optional[str]:
|
||||
def _find_config_file(path: str) -> str | None:
|
||||
# on windows if the homedir isn't detected this returns back `~`
|
||||
home = os.path.expanduser("~")
|
||||
try:
|
||||
|
|
@ -55,11 +53,11 @@ def _find_config_file(path: str) -> Optional[str]:
|
|||
|
||||
|
||||
def load_config(
|
||||
config: Optional[str],
|
||||
extra: List[str],
|
||||
config: str | None,
|
||||
extra: list[str],
|
||||
*,
|
||||
isolated: bool = False,
|
||||
) -> Tuple[configparser.RawConfigParser, str]:
|
||||
) -> tuple[configparser.RawConfigParser, str]:
|
||||
"""Load the configuration given the user options.
|
||||
|
||||
- in ``isolated`` mode, return an empty configuration
|
||||
|
|
@ -97,7 +95,7 @@ def parse_config(
|
|||
option_manager: OptionManager,
|
||||
cfg: configparser.RawConfigParser,
|
||||
cfg_dir: str,
|
||||
) -> Dict[str, Any]:
|
||||
) -> dict[str, Any]:
|
||||
"""Parse and normalize the typed configuration options."""
|
||||
if "flake8" not in cfg:
|
||||
return {}
|
||||
|
|
|
|||
|
|
@ -1,18 +1,14 @@
|
|||
"""Option handling and Option management logic."""
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import enum
|
||||
import functools
|
||||
import logging
|
||||
from typing import Any
|
||||
from typing import Callable
|
||||
from typing import Dict
|
||||
from typing import List
|
||||
from typing import Mapping
|
||||
from typing import Optional
|
||||
from typing import Sequence
|
||||
from typing import Tuple
|
||||
from typing import Type
|
||||
from typing import Union
|
||||
|
||||
from flake8 import utils
|
||||
from flake8.plugins.finder import Plugins
|
||||
|
|
@ -24,7 +20,7 @@ LOG = logging.getLogger(__name__)
|
|||
_ARG = enum.Enum("_ARG", "NO")
|
||||
|
||||
|
||||
_optparse_callable_map: Dict[str, Union[Type[Any], _ARG]] = {
|
||||
_optparse_callable_map: dict[str, type[Any] | _ARG] = {
|
||||
"int": int,
|
||||
"long": int,
|
||||
"string": str,
|
||||
|
|
@ -44,7 +40,7 @@ class _CallbackAction(argparse.Action):
|
|||
*args: Any,
|
||||
callback: Callable[..., Any],
|
||||
callback_args: Sequence[Any] = (),
|
||||
callback_kwargs: Optional[Dict[str, Any]] = None,
|
||||
callback_kwargs: dict[str, Any] | None = None,
|
||||
**kwargs: Any,
|
||||
) -> None:
|
||||
self._callback = callback
|
||||
|
|
@ -56,8 +52,8 @@ class _CallbackAction(argparse.Action):
|
|||
self,
|
||||
parser: argparse.ArgumentParser,
|
||||
namespace: argparse.Namespace,
|
||||
values: Optional[Union[Sequence[str], str]],
|
||||
option_string: Optional[str] = None,
|
||||
values: Sequence[str] | str | None,
|
||||
option_string: str | None = None,
|
||||
) -> None:
|
||||
if not values:
|
||||
values = None
|
||||
|
|
@ -78,8 +74,8 @@ def _flake8_normalize(
|
|||
*args: str,
|
||||
comma_separated_list: bool = False,
|
||||
normalize_paths: bool = False,
|
||||
) -> Union[str, List[str]]:
|
||||
ret: Union[str, List[str]] = value
|
||||
) -> str | list[str]:
|
||||
ret: str | list[str] = value
|
||||
if comma_separated_list and isinstance(ret, str):
|
||||
ret = utils.parse_comma_separated_list(value)
|
||||
|
||||
|
|
@ -97,24 +93,24 @@ class Option:
|
|||
|
||||
def __init__(
|
||||
self,
|
||||
short_option_name: Union[str, _ARG] = _ARG.NO,
|
||||
long_option_name: Union[str, _ARG] = _ARG.NO,
|
||||
short_option_name: str | _ARG = _ARG.NO,
|
||||
long_option_name: str | _ARG = _ARG.NO,
|
||||
# Options below here are taken from the optparse.Option class
|
||||
action: Union[str, Type[argparse.Action], _ARG] = _ARG.NO,
|
||||
default: Union[Any, _ARG] = _ARG.NO,
|
||||
type: Union[str, Callable[..., Any], _ARG] = _ARG.NO,
|
||||
dest: Union[str, _ARG] = _ARG.NO,
|
||||
nargs: Union[int, str, _ARG] = _ARG.NO,
|
||||
const: Union[Any, _ARG] = _ARG.NO,
|
||||
choices: Union[Sequence[Any], _ARG] = _ARG.NO,
|
||||
help: Union[str, _ARG] = _ARG.NO,
|
||||
metavar: Union[str, _ARG] = _ARG.NO,
|
||||
action: str | type[argparse.Action] | _ARG = _ARG.NO,
|
||||
default: Any | _ARG = _ARG.NO,
|
||||
type: str | Callable[..., Any] | _ARG = _ARG.NO,
|
||||
dest: str | _ARG = _ARG.NO,
|
||||
nargs: int | str | _ARG = _ARG.NO,
|
||||
const: Any | _ARG = _ARG.NO,
|
||||
choices: Sequence[Any] | _ARG = _ARG.NO,
|
||||
help: str | _ARG = _ARG.NO,
|
||||
metavar: str | _ARG = _ARG.NO,
|
||||
# deprecated optparse-only options
|
||||
callback: Union[Callable[..., Any], _ARG] = _ARG.NO,
|
||||
callback_args: Union[Sequence[Any], _ARG] = _ARG.NO,
|
||||
callback_kwargs: Union[Mapping[str, Any], _ARG] = _ARG.NO,
|
||||
callback: Callable[..., Any] | _ARG = _ARG.NO,
|
||||
callback_args: Sequence[Any] | _ARG = _ARG.NO,
|
||||
callback_kwargs: Mapping[str, Any] | _ARG = _ARG.NO,
|
||||
# Options below are taken from argparse.ArgumentParser.add_argument
|
||||
required: Union[bool, _ARG] = _ARG.NO,
|
||||
required: bool | _ARG = _ARG.NO,
|
||||
# Options below here are specific to Flake8
|
||||
parse_from_config: bool = False,
|
||||
comma_separated_list: bool = False,
|
||||
|
|
@ -247,7 +243,7 @@ class Option:
|
|||
self.help = help
|
||||
self.metavar = metavar
|
||||
self.required = required
|
||||
self.option_kwargs: Dict[str, Union[Any, _ARG]] = {
|
||||
self.option_kwargs: dict[str, Any | _ARG] = {
|
||||
"action": self.action,
|
||||
"default": self.default,
|
||||
"type": self.type,
|
||||
|
|
@ -268,7 +264,7 @@ class Option:
|
|||
self.comma_separated_list = comma_separated_list
|
||||
self.normalize_paths = normalize_paths
|
||||
|
||||
self.config_name: Optional[str] = None
|
||||
self.config_name: str | None = None
|
||||
if parse_from_config:
|
||||
if long_option_name is _ARG.NO:
|
||||
raise ValueError(
|
||||
|
|
@ -280,7 +276,7 @@ class Option:
|
|||
self._opt = None
|
||||
|
||||
@property
|
||||
def filtered_option_kwargs(self) -> Dict[str, Any]:
|
||||
def filtered_option_kwargs(self) -> dict[str, Any]:
|
||||
"""Return any actually-specified arguments."""
|
||||
return {
|
||||
k: v for k, v in self.option_kwargs.items() if v is not _ARG.NO
|
||||
|
|
@ -307,7 +303,7 @@ class Option:
|
|||
|
||||
return value
|
||||
|
||||
def to_argparse(self) -> Tuple[List[str], Dict[str, Any]]:
|
||||
def to_argparse(self) -> tuple[list[str], dict[str, Any]]:
|
||||
"""Convert a Flake8 Option to argparse ``add_argument`` arguments."""
|
||||
return self.option_args, self.filtered_option_kwargs
|
||||
|
||||
|
|
@ -320,7 +316,7 @@ class OptionManager:
|
|||
*,
|
||||
version: str,
|
||||
plugin_versions: str,
|
||||
parents: List[argparse.ArgumentParser],
|
||||
parents: list[argparse.ArgumentParser],
|
||||
) -> None:
|
||||
"""Initialize an instance of an OptionManager.
|
||||
|
||||
|
|
@ -350,17 +346,17 @@ class OptionManager:
|
|||
)
|
||||
self.parser.add_argument("filenames", nargs="*", metavar="filename")
|
||||
|
||||
self.config_options_dict: Dict[str, Option] = {}
|
||||
self.options: List[Option] = []
|
||||
self.extended_default_ignore: List[str] = []
|
||||
self.extended_default_select: List[str] = []
|
||||
self.config_options_dict: dict[str, Option] = {}
|
||||
self.options: list[Option] = []
|
||||
self.extended_default_ignore: list[str] = []
|
||||
self.extended_default_select: list[str] = []
|
||||
|
||||
self._current_group: Optional[argparse._ArgumentGroup] = None
|
||||
self._current_group: argparse._ArgumentGroup | None = None
|
||||
|
||||
# TODO: maybe make this a free function to reduce api surface area
|
||||
def register_plugins(self, plugins: Plugins) -> None:
|
||||
"""Register the plugin options (if needed)."""
|
||||
groups: Dict[str, argparse._ArgumentGroup] = {}
|
||||
groups: dict[str, argparse._ArgumentGroup] = {}
|
||||
|
||||
def _set_group(name: str) -> None:
|
||||
try:
|
||||
|
|
@ -428,8 +424,8 @@ class OptionManager:
|
|||
|
||||
def parse_args(
|
||||
self,
|
||||
args: Optional[Sequence[str]] = None,
|
||||
values: Optional[argparse.Namespace] = None,
|
||||
args: Sequence[str] | None = None,
|
||||
values: argparse.Namespace | None = None,
|
||||
) -> argparse.Namespace:
|
||||
"""Proxy to calling the OptionParser's parse_args method."""
|
||||
if values:
|
||||
|
|
|
|||
|
|
@ -1 +1,2 @@
|
|||
"""Submodule of built-in plugins and plugin managers."""
|
||||
from __future__ import annotations
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
"""Functions related to finding and loading plugins."""
|
||||
from __future__ import annotations
|
||||
|
||||
import configparser
|
||||
import inspect
|
||||
import itertools
|
||||
|
|
@ -6,14 +8,9 @@ import logging
|
|||
import re
|
||||
import sys
|
||||
from typing import Any
|
||||
from typing import Dict
|
||||
from typing import FrozenSet
|
||||
from typing import Generator
|
||||
from typing import Iterable
|
||||
from typing import List
|
||||
from typing import NamedTuple
|
||||
from typing import Optional
|
||||
from typing import Tuple
|
||||
|
||||
from flake8 import utils
|
||||
from flake8._compat import importlib_metadata
|
||||
|
|
@ -45,7 +42,7 @@ class LoadedPlugin(NamedTuple):
|
|||
|
||||
plugin: Plugin
|
||||
obj: Any
|
||||
parameters: Dict[str, bool]
|
||||
parameters: dict[str, bool]
|
||||
|
||||
@property
|
||||
def entry_name(self) -> str:
|
||||
|
|
@ -61,17 +58,17 @@ class LoadedPlugin(NamedTuple):
|
|||
class Checkers(NamedTuple):
|
||||
"""Classified plugins needed for checking."""
|
||||
|
||||
tree: List[LoadedPlugin]
|
||||
logical_line: List[LoadedPlugin]
|
||||
physical_line: List[LoadedPlugin]
|
||||
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]
|
||||
reporters: dict[str, LoadedPlugin]
|
||||
disabled: list[LoadedPlugin]
|
||||
|
||||
def all_plugins(self) -> Generator[LoadedPlugin, None, None]:
|
||||
"""Return an iterator over all :class:`LoadedPlugin`s."""
|
||||
|
|
@ -96,12 +93,12 @@ class Plugins(NamedTuple):
|
|||
class PluginOptions(NamedTuple):
|
||||
"""Options related to plugin loading."""
|
||||
|
||||
local_plugin_paths: Tuple[str, ...]
|
||||
enable_extensions: FrozenSet[str]
|
||||
require_plugins: FrozenSet[str]
|
||||
local_plugin_paths: tuple[str, ...]
|
||||
enable_extensions: frozenset[str]
|
||||
require_plugins: frozenset[str]
|
||||
|
||||
@classmethod
|
||||
def blank(cls) -> "PluginOptions":
|
||||
def blank(cls) -> PluginOptions:
|
||||
"""Make a blank PluginOptions, mostly used for tests."""
|
||||
return cls(
|
||||
local_plugin_paths=(),
|
||||
|
|
@ -113,8 +110,8 @@ class PluginOptions(NamedTuple):
|
|||
def _parse_option(
|
||||
cfg: configparser.RawConfigParser,
|
||||
cfg_opt_name: str,
|
||||
opt: Optional[str],
|
||||
) -> List[str]:
|
||||
opt: str | None,
|
||||
) -> list[str]:
|
||||
# specified on commandline: use that
|
||||
if opt is not None:
|
||||
return utils.parse_comma_separated_list(opt)
|
||||
|
|
@ -133,8 +130,8 @@ def parse_plugin_options(
|
|||
cfg: configparser.RawConfigParser,
|
||||
cfg_dir: str,
|
||||
*,
|
||||
enable_extensions: Optional[str],
|
||||
require_plugins: Optional[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()
|
||||
|
|
@ -231,8 +228,8 @@ def _find_local_plugins(
|
|||
|
||||
|
||||
def _check_required_plugins(
|
||||
plugins: List[Plugin],
|
||||
expected: FrozenSet[str],
|
||||
plugins: list[Plugin],
|
||||
expected: frozenset[str],
|
||||
) -> None:
|
||||
plugin_names = {
|
||||
utils.normalize_pypi_name(plugin.package) for plugin in plugins
|
||||
|
|
@ -252,7 +249,7 @@ def _check_required_plugins(
|
|||
def find_plugins(
|
||||
cfg: configparser.RawConfigParser,
|
||||
opts: PluginOptions,
|
||||
) -> List[Plugin]:
|
||||
) -> list[Plugin]:
|
||||
"""Discovers all plugins (but does not load them)."""
|
||||
ret = [*_find_importlib_plugins(), *_find_local_plugins(cfg)]
|
||||
|
||||
|
|
@ -264,7 +261,7 @@ def find_plugins(
|
|||
return ret
|
||||
|
||||
|
||||
def _parameters_for(func: Any) -> Dict[str, bool]:
|
||||
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
|
||||
|
|
@ -305,15 +302,15 @@ def _load_plugin(plugin: Plugin) -> LoadedPlugin:
|
|||
|
||||
|
||||
def _import_plugins(
|
||||
plugins: List[Plugin],
|
||||
plugins: list[Plugin],
|
||||
opts: PluginOptions,
|
||||
) -> List[LoadedPlugin]:
|
||||
) -> list[LoadedPlugin]:
|
||||
sys.path.extend(opts.local_plugin_paths)
|
||||
return [_load_plugin(p) for p in plugins]
|
||||
|
||||
|
||||
def _classify_plugins(
|
||||
plugins: List[LoadedPlugin],
|
||||
plugins: list[LoadedPlugin],
|
||||
opts: PluginOptions,
|
||||
) -> Plugins:
|
||||
tree = []
|
||||
|
|
@ -358,7 +355,7 @@ def _classify_plugins(
|
|||
|
||||
|
||||
def load_plugins(
|
||||
plugins: List[Plugin],
|
||||
plugins: list[Plugin],
|
||||
opts: PluginOptions,
|
||||
) -> Plugins:
|
||||
"""Load and classify all flake8 plugins.
|
||||
|
|
|
|||
|
|
@ -1,8 +1,9 @@
|
|||
"""Generated using ./bin/gen-pycodestyle-plugin."""
|
||||
# fmt: off
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Any
|
||||
from typing import Generator
|
||||
from typing import Tuple
|
||||
|
||||
from pycodestyle import ambiguous_identifier as _ambiguous_identifier
|
||||
from pycodestyle import bare_except as _bare_except
|
||||
|
|
@ -60,7 +61,7 @@ def pycodestyle_logical(
|
|||
previous_unindented_logical_line: Any,
|
||||
tokens: Any,
|
||||
verbose: Any,
|
||||
) -> Generator[Tuple[int, str], None, None]:
|
||||
) -> Generator[tuple[int, str], None, None]:
|
||||
"""Run pycodestyle logical checks."""
|
||||
yield from _ambiguous_identifier(logical_line, tokens)
|
||||
yield from _bare_except(logical_line, noqa)
|
||||
|
|
@ -104,7 +105,7 @@ def pycodestyle_physical(
|
|||
noqa: Any,
|
||||
physical_line: Any,
|
||||
total_lines: Any,
|
||||
) -> Generator[Tuple[int, str], None, None]:
|
||||
) -> 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:
|
||||
|
|
|
|||
|
|
@ -1,13 +1,12 @@
|
|||
"""Plugin built-in to Flake8 to treat pyflakes as a plugin."""
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import ast
|
||||
import os
|
||||
import tokenize
|
||||
from typing import Any
|
||||
from typing import Generator
|
||||
from typing import List
|
||||
from typing import Tuple
|
||||
from typing import Type
|
||||
|
||||
import pyflakes.checker
|
||||
|
||||
|
|
@ -68,13 +67,13 @@ class FlakesChecker(pyflakes.checker.Checker):
|
|||
"""Subclass the Pyflakes checker to conform with the flake8 API."""
|
||||
|
||||
with_doctest = False
|
||||
include_in_doctest: List[str] = []
|
||||
exclude_from_doctest: List[str] = []
|
||||
include_in_doctest: list[str] = []
|
||||
exclude_from_doctest: list[str] = []
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
tree: ast.AST,
|
||||
file_tokens: List[tokenize.TokenInfo],
|
||||
file_tokens: list[tokenize.TokenInfo],
|
||||
filename: str,
|
||||
) -> None:
|
||||
"""Initialize the PyFlakes plugin with an AST tree and filename."""
|
||||
|
|
@ -180,7 +179,7 @@ class FlakesChecker(pyflakes.checker.Checker):
|
|||
f"both for doctesting."
|
||||
)
|
||||
|
||||
def run(self) -> Generator[Tuple[int, int, str, Type[Any]], None, None]:
|
||||
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)
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
"""Functions for construcing the requested report plugin."""
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import logging
|
||||
from typing import Dict
|
||||
|
||||
from flake8.formatting.base import BaseFormatter
|
||||
from flake8.plugins.finder import LoadedPlugin
|
||||
|
|
@ -10,7 +11,7 @@ LOG = logging.getLogger(__name__)
|
|||
|
||||
|
||||
def make(
|
||||
reporters: Dict[str, LoadedPlugin],
|
||||
reporters: dict[str, LoadedPlugin],
|
||||
options: argparse.Namespace,
|
||||
) -> BaseFormatter:
|
||||
"""Make the formatter from the requested user options.
|
||||
|
|
|
|||
|
|
@ -1,14 +1,14 @@
|
|||
"""Module containing our file processor that tokenizes a file for checks."""
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import ast
|
||||
import contextlib
|
||||
import logging
|
||||
import tokenize
|
||||
from typing import Any
|
||||
from typing import Dict
|
||||
from typing import Generator
|
||||
from typing import List
|
||||
from typing import Optional
|
||||
from typing import Tuple
|
||||
|
||||
from flake8 import defaults
|
||||
|
|
@ -61,7 +61,7 @@ class FileProcessor:
|
|||
self,
|
||||
filename: str,
|
||||
options: argparse.Namespace,
|
||||
lines: Optional[List[str]] = None,
|
||||
lines: list[str] | None = None,
|
||||
) -> None:
|
||||
"""Initialice our file processor.
|
||||
|
||||
|
|
@ -78,13 +78,13 @@ class FileProcessor:
|
|||
#: Number of blank lines
|
||||
self.blank_lines = 0
|
||||
#: Checker states for each plugin?
|
||||
self._checker_states: Dict[str, Dict[Any, Any]] = {}
|
||||
self._checker_states: dict[str, dict[Any, Any]] = {}
|
||||
#: Current checker state
|
||||
self.checker_state: Dict[Any, Any] = {}
|
||||
self.checker_state: dict[Any, Any] = {}
|
||||
#: User provided option for hang closing
|
||||
self.hang_closing = options.hang_closing
|
||||
#: Character used for indentation
|
||||
self.indent_char: Optional[str] = None
|
||||
self.indent_char: str | None = None
|
||||
#: Current level of indentation
|
||||
self.indent_level = 0
|
||||
#: Number of spaces used for indentation
|
||||
|
|
@ -106,19 +106,19 @@ class FileProcessor:
|
|||
#: Previous unindented (i.e. top-level) logical line
|
||||
self.previous_unindented_logical_line = ""
|
||||
#: Current set of tokens
|
||||
self.tokens: List[tokenize.TokenInfo] = []
|
||||
self.tokens: list[tokenize.TokenInfo] = []
|
||||
#: Total number of lines in the file
|
||||
self.total_lines = len(self.lines)
|
||||
#: Verbosity level of Flake8
|
||||
self.verbose = options.verbose
|
||||
#: Statistics dictionary
|
||||
self.statistics = {"logical lines": 0}
|
||||
self._file_tokens: Optional[List[tokenize.TokenInfo]] = None
|
||||
self._file_tokens: list[tokenize.TokenInfo] | None = None
|
||||
# map from line number to the line we'll search for `noqa` in
|
||||
self._noqa_line_mapping: Optional[Dict[int, str]] = None
|
||||
self._noqa_line_mapping: dict[int, str] | None = None
|
||||
|
||||
@property
|
||||
def file_tokens(self) -> List[tokenize.TokenInfo]:
|
||||
def file_tokens(self) -> list[tokenize.TokenInfo]:
|
||||
"""Return the complete set of tokens for a file."""
|
||||
if self._file_tokens is None:
|
||||
line_iter = iter(self.lines)
|
||||
|
|
@ -217,7 +217,7 @@ class FileProcessor:
|
|||
"""Build an abstract syntax tree from the list of lines."""
|
||||
return ast.parse("".join(self.lines))
|
||||
|
||||
def build_logical_line(self) -> Tuple[str, str, _LogicalMapping]:
|
||||
def build_logical_line(self) -> tuple[str, str, _LogicalMapping]:
|
||||
"""Build a logical line from the current tokens list."""
|
||||
comments, logical, mapping_list = self.build_logical_line_tokens()
|
||||
joined_comments = "".join(comments)
|
||||
|
|
@ -240,9 +240,9 @@ class FileProcessor:
|
|||
|
||||
def keyword_arguments_for(
|
||||
self,
|
||||
parameters: Dict[str, bool],
|
||||
arguments: Dict[str, Any],
|
||||
) -> Dict[str, Any]:
|
||||
parameters: dict[str, bool],
|
||||
arguments: dict[str, Any],
|
||||
) -> dict[str, Any]:
|
||||
"""Generate the keyword arguments for a list of parameters."""
|
||||
ret = {}
|
||||
for param, required in parameters.items():
|
||||
|
|
@ -269,12 +269,12 @@ class FileProcessor:
|
|||
self.tokens.append(token)
|
||||
yield token
|
||||
|
||||
def _noqa_line_range(self, min_line: int, max_line: int) -> Dict[int, str]:
|
||||
def _noqa_line_range(self, min_line: int, max_line: int) -> dict[int, str]:
|
||||
line_range = range(min_line, max_line + 1)
|
||||
joined = "".join(self.lines[min_line - 1 : max_line])
|
||||
return dict.fromkeys(line_range, joined)
|
||||
|
||||
def noqa_line_for(self, line_number: int) -> Optional[str]:
|
||||
def noqa_line_for(self, line_number: int) -> str | None:
|
||||
"""Retrieve the line which will be used to determine noqa."""
|
||||
if self._noqa_line_mapping is None:
|
||||
try:
|
||||
|
|
@ -324,7 +324,7 @@ class FileProcessor:
|
|||
self.indent_char = line[0]
|
||||
return line
|
||||
|
||||
def read_lines(self) -> List[str]:
|
||||
def read_lines(self) -> list[str]:
|
||||
"""Read the lines for this file checker."""
|
||||
if self.filename is None or self.filename == "-":
|
||||
self.filename = self.options.stdin_display_name or "stdin"
|
||||
|
|
@ -333,7 +333,7 @@ class FileProcessor:
|
|||
lines = self.read_lines_from_filename()
|
||||
return lines
|
||||
|
||||
def read_lines_from_filename(self) -> List[str]:
|
||||
def read_lines_from_filename(self) -> list[str]:
|
||||
"""Read the lines for a file."""
|
||||
try:
|
||||
with tokenize.open(self.filename) as fd:
|
||||
|
|
@ -344,7 +344,7 @@ class FileProcessor:
|
|||
with open(self.filename, encoding="latin-1") as fd:
|
||||
return fd.readlines()
|
||||
|
||||
def read_lines_from_stdin(self) -> List[str]:
|
||||
def read_lines_from_stdin(self) -> list[str]:
|
||||
"""Read the lines from standard in."""
|
||||
return utils.stdin_get_lines()
|
||||
|
||||
|
|
|
|||
|
|
@ -1,9 +1,8 @@
|
|||
"""Statistic collection logic for Flake8."""
|
||||
from typing import Dict
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Generator
|
||||
from typing import List
|
||||
from typing import NamedTuple
|
||||
from typing import Optional
|
||||
|
||||
from flake8.violation import Violation
|
||||
|
||||
|
|
@ -13,9 +12,9 @@ class Statistics:
|
|||
|
||||
def __init__(self) -> None:
|
||||
"""Initialize the underlying dictionary for our statistics."""
|
||||
self._store: Dict[Key, "Statistic"] = {}
|
||||
self._store: dict[Key, Statistic] = {}
|
||||
|
||||
def error_codes(self) -> List[str]:
|
||||
def error_codes(self) -> list[str]:
|
||||
"""Return all unique error codes stored.
|
||||
|
||||
:returns:
|
||||
|
|
@ -23,7 +22,7 @@ class Statistics:
|
|||
"""
|
||||
return sorted({key.code for key in self._store})
|
||||
|
||||
def record(self, error: "Violation") -> None:
|
||||
def record(self, error: Violation) -> None:
|
||||
"""Add the fact that the error was seen in the file.
|
||||
|
||||
:param error:
|
||||
|
|
@ -36,8 +35,8 @@ class Statistics:
|
|||
self._store[key].increment()
|
||||
|
||||
def statistics_for(
|
||||
self, prefix: str, filename: Optional[str] = None
|
||||
) -> Generator["Statistic", None, None]:
|
||||
self, prefix: str, filename: str | None = None
|
||||
) -> Generator[Statistic, None, None]:
|
||||
"""Generate statistics for the prefix and filename.
|
||||
|
||||
If you have a :class:`Statistics` object that has recorded errors,
|
||||
|
|
@ -79,11 +78,11 @@ class Key(NamedTuple):
|
|||
code: str
|
||||
|
||||
@classmethod
|
||||
def create_from(cls, error: "Violation") -> "Key":
|
||||
def create_from(cls, error: Violation) -> Key:
|
||||
"""Create a Key from :class:`flake8.violation.Violation`."""
|
||||
return cls(filename=error.filename, code=error.code)
|
||||
|
||||
def matches(self, prefix: str, filename: Optional[str]) -> bool:
|
||||
def matches(self, prefix: str, filename: str | None) -> bool:
|
||||
"""Determine if this key matches some constraints.
|
||||
|
||||
:param prefix:
|
||||
|
|
@ -118,7 +117,7 @@ class Statistic:
|
|||
self.count = count
|
||||
|
||||
@classmethod
|
||||
def create_from(cls, error: "Violation") -> "Statistic":
|
||||
def create_from(cls, error: Violation) -> Statistic:
|
||||
"""Create a Statistic from a :class:`flake8.violation.Violation`."""
|
||||
return cls(
|
||||
error_code=error.code,
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
"""Implementation of the StyleGuide used by Flake8."""
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import contextlib
|
||||
import copy
|
||||
|
|
@ -6,14 +8,8 @@ import enum
|
|||
import functools
|
||||
import itertools
|
||||
import logging
|
||||
from typing import Dict
|
||||
from typing import Generator
|
||||
from typing import List
|
||||
from typing import Optional
|
||||
from typing import Sequence
|
||||
from typing import Set
|
||||
from typing import Tuple
|
||||
from typing import Union
|
||||
|
||||
from flake8 import defaults
|
||||
from flake8 import statistics
|
||||
|
|
@ -49,20 +45,20 @@ class Decision(enum.Enum):
|
|||
|
||||
def _explicitly_chosen(
|
||||
*,
|
||||
option: Optional[List[str]],
|
||||
extend: Optional[List[str]],
|
||||
) -> Tuple[str, ...]:
|
||||
option: list[str] | None,
|
||||
extend: list[str] | None,
|
||||
) -> tuple[str, ...]:
|
||||
ret = [*(option or []), *(extend or [])]
|
||||
return tuple(sorted(ret, reverse=True))
|
||||
|
||||
|
||||
def _select_ignore(
|
||||
*,
|
||||
option: Optional[List[str]],
|
||||
default: Tuple[str, ...],
|
||||
extended_default: List[str],
|
||||
extend: Optional[List[str]],
|
||||
) -> Tuple[str, ...]:
|
||||
option: list[str] | None,
|
||||
default: tuple[str, ...],
|
||||
extended_default: list[str],
|
||||
extend: list[str] | None,
|
||||
) -> tuple[str, ...]:
|
||||
# option was explicitly set, ignore the default and extended default
|
||||
if option is not None:
|
||||
ret = [*option, *(extend or [])]
|
||||
|
|
@ -80,7 +76,7 @@ class DecisionEngine:
|
|||
|
||||
def __init__(self, options: argparse.Namespace) -> None:
|
||||
"""Initialize the engine."""
|
||||
self.cache: Dict[str, Decision] = {}
|
||||
self.cache: dict[str, Decision] = {}
|
||||
|
||||
self.selected_explicitly = _explicitly_chosen(
|
||||
option=options.select,
|
||||
|
|
@ -104,7 +100,7 @@ class DecisionEngine:
|
|||
extend=options.extend_ignore,
|
||||
)
|
||||
|
||||
def was_selected(self, code: str) -> Union[Selected, Ignored]:
|
||||
def was_selected(self, code: str) -> Selected | Ignored:
|
||||
"""Determine if the code has been selected by the user.
|
||||
|
||||
:param code: The code for the check that has been run.
|
||||
|
|
@ -122,7 +118,7 @@ class DecisionEngine:
|
|||
else:
|
||||
return Ignored.Implicitly
|
||||
|
||||
def was_ignored(self, code: str) -> Union[Selected, Ignored]:
|
||||
def was_ignored(self, code: str) -> Selected | Ignored:
|
||||
"""Determine if the code has been ignored by the user.
|
||||
|
||||
:param code:
|
||||
|
|
@ -211,7 +207,7 @@ class StyleGuideManager:
|
|||
self,
|
||||
options: argparse.Namespace,
|
||||
formatter: base_formatter.BaseFormatter,
|
||||
decider: Optional[DecisionEngine] = None,
|
||||
decider: DecisionEngine | None = None,
|
||||
) -> None:
|
||||
"""Initialize our StyleGuide.
|
||||
|
||||
|
|
@ -221,7 +217,7 @@ class StyleGuideManager:
|
|||
self.formatter = formatter
|
||||
self.stats = statistics.Statistics()
|
||||
self.decider = decider or DecisionEngine(options)
|
||||
self.style_guides: List[StyleGuide] = []
|
||||
self.style_guides: list[StyleGuide] = []
|
||||
self.default_style_guide = StyleGuide(
|
||||
options, formatter, self.stats, decider=decider
|
||||
)
|
||||
|
|
@ -238,7 +234,7 @@ class StyleGuideManager:
|
|||
|
||||
def populate_style_guides_with(
|
||||
self, options: argparse.Namespace
|
||||
) -> Generator["StyleGuide", None, None]:
|
||||
) -> Generator[StyleGuide, None, None]:
|
||||
"""Generate style guides from the per-file-ignores option.
|
||||
|
||||
:param options:
|
||||
|
|
@ -252,7 +248,7 @@ class StyleGuideManager:
|
|||
filename=filename, extend_ignore_with=violations
|
||||
)
|
||||
|
||||
def _style_guide_for(self, filename: str) -> "StyleGuide":
|
||||
def _style_guide_for(self, filename: str) -> StyleGuide:
|
||||
"""Find the StyleGuide for the filename in particular."""
|
||||
return max(
|
||||
(g for g in self.style_guides if g.applies_to(filename)),
|
||||
|
|
@ -262,7 +258,7 @@ class StyleGuideManager:
|
|||
@contextlib.contextmanager
|
||||
def processing_file(
|
||||
self, filename: str
|
||||
) -> Generator["StyleGuide", None, None]:
|
||||
) -> Generator[StyleGuide, None, None]:
|
||||
"""Record the fact that we're processing the file's results."""
|
||||
guide = self.style_guide_for(filename)
|
||||
with guide.processing_file(filename):
|
||||
|
|
@ -275,7 +271,7 @@ class StyleGuideManager:
|
|||
line_number: int,
|
||||
column_number: int,
|
||||
text: str,
|
||||
physical_line: Optional[str] = None,
|
||||
physical_line: str | None = None,
|
||||
) -> int:
|
||||
"""Handle an error reported by a check.
|
||||
|
||||
|
|
@ -302,7 +298,7 @@ class StyleGuideManager:
|
|||
code, filename, line_number, column_number, text, physical_line
|
||||
)
|
||||
|
||||
def add_diff_ranges(self, diffinfo: Dict[str, Set[int]]) -> None:
|
||||
def add_diff_ranges(self, diffinfo: dict[str, set[int]]) -> None:
|
||||
"""Update the StyleGuides to filter out information not in the diff.
|
||||
|
||||
This provides information to the underlying StyleGuides so that only
|
||||
|
|
@ -323,8 +319,8 @@ class StyleGuide:
|
|||
options: argparse.Namespace,
|
||||
formatter: base_formatter.BaseFormatter,
|
||||
stats: statistics.Statistics,
|
||||
filename: Optional[str] = None,
|
||||
decider: Optional[DecisionEngine] = None,
|
||||
filename: str | None = None,
|
||||
decider: DecisionEngine | None = None,
|
||||
):
|
||||
"""Initialize our StyleGuide.
|
||||
|
||||
|
|
@ -337,7 +333,7 @@ class StyleGuide:
|
|||
self.filename = filename
|
||||
if self.filename:
|
||||
self.filename = utils.normalize_path(self.filename)
|
||||
self._parsed_diff: Dict[str, Set[int]] = {}
|
||||
self._parsed_diff: dict[str, set[int]] = {}
|
||||
|
||||
def __repr__(self) -> str:
|
||||
"""Make it easier to debug which StyleGuide we're using."""
|
||||
|
|
@ -345,9 +341,9 @@ class StyleGuide:
|
|||
|
||||
def copy(
|
||||
self,
|
||||
filename: Optional[str] = None,
|
||||
extend_ignore_with: Optional[Sequence[str]] = None,
|
||||
) -> "StyleGuide":
|
||||
filename: str | None = None,
|
||||
extend_ignore_with: Sequence[str] | None = None,
|
||||
) -> StyleGuide:
|
||||
"""Create a copy of this style guide with different values."""
|
||||
filename = filename or self.filename
|
||||
options = copy.deepcopy(self.options)
|
||||
|
|
@ -360,7 +356,7 @@ class StyleGuide:
|
|||
@contextlib.contextmanager
|
||||
def processing_file(
|
||||
self, filename: str
|
||||
) -> Generator["StyleGuide", None, None]:
|
||||
) -> Generator[StyleGuide, None, None]:
|
||||
"""Record the fact that we're processing the file's results."""
|
||||
self.formatter.beginning(filename)
|
||||
yield self
|
||||
|
|
@ -405,7 +401,7 @@ class StyleGuide:
|
|||
line_number: int,
|
||||
column_number: int,
|
||||
text: str,
|
||||
physical_line: Optional[str] = None,
|
||||
physical_line: str | None = None,
|
||||
) -> int:
|
||||
"""Handle an error reported by a check.
|
||||
|
||||
|
|
@ -451,7 +447,7 @@ class StyleGuide:
|
|||
return 1
|
||||
return 0
|
||||
|
||||
def add_diff_ranges(self, diffinfo: Dict[str, Set[int]]) -> None:
|
||||
def add_diff_ranges(self, diffinfo: dict[str, set[int]]) -> None:
|
||||
"""Update the StyleGuide to filter out information not in the diff.
|
||||
|
||||
This provides information to the StyleGuide so that only the errors
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
"""Utility methods for flake8."""
|
||||
from __future__ import annotations
|
||||
|
||||
import collections
|
||||
import fnmatch as _fnmatch
|
||||
import functools
|
||||
|
|
@ -10,15 +12,9 @@ import re
|
|||
import sys
|
||||
import textwrap
|
||||
import tokenize
|
||||
from typing import Dict
|
||||
from typing import List
|
||||
from typing import NamedTuple
|
||||
from typing import Optional
|
||||
from typing import Pattern
|
||||
from typing import Sequence
|
||||
from typing import Set
|
||||
from typing import Tuple
|
||||
from typing import Union
|
||||
|
||||
from flake8 import exceptions
|
||||
|
||||
|
|
@ -30,7 +26,7 @@ NORMALIZE_PACKAGE_NAME_RE = re.compile(r"[-_.]+")
|
|||
|
||||
def parse_comma_separated_list(
|
||||
value: str, regexp: Pattern[str] = COMMA_SEPARATED_LIST_RE
|
||||
) -> List[str]:
|
||||
) -> list[str]:
|
||||
"""Parse a comma-separated list.
|
||||
|
||||
:param value:
|
||||
|
|
@ -64,7 +60,7 @@ _FILE_LIST_TOKEN_TYPES = [
|
|||
]
|
||||
|
||||
|
||||
def _tokenize_files_to_codes_mapping(value: str) -> List[_Token]:
|
||||
def _tokenize_files_to_codes_mapping(value: str) -> list[_Token]:
|
||||
tokens = []
|
||||
i = 0
|
||||
while i < len(value):
|
||||
|
|
@ -82,8 +78,8 @@ def _tokenize_files_to_codes_mapping(value: str) -> List[_Token]:
|
|||
|
||||
|
||||
def parse_files_to_codes_mapping( # noqa: C901
|
||||
value_: Union[Sequence[str], str]
|
||||
) -> List[Tuple[str, List[str]]]:
|
||||
value_: Sequence[str] | str,
|
||||
) -> list[tuple[str, list[str]]]:
|
||||
"""Parse a files-to-codes mapping.
|
||||
|
||||
A files-to-codes mapping a sequence of values specified as
|
||||
|
|
@ -97,15 +93,15 @@ def parse_files_to_codes_mapping( # noqa: C901
|
|||
else:
|
||||
value = value_
|
||||
|
||||
ret: List[Tuple[str, List[str]]] = []
|
||||
ret: list[tuple[str, list[str]]] = []
|
||||
if not value.strip():
|
||||
return ret
|
||||
|
||||
class State:
|
||||
seen_sep = True
|
||||
seen_colon = False
|
||||
filenames: List[str] = []
|
||||
codes: List[str] = []
|
||||
filenames: list[str] = []
|
||||
codes: list[str] = []
|
||||
|
||||
def _reset() -> None:
|
||||
if State.codes:
|
||||
|
|
@ -157,7 +153,7 @@ def parse_files_to_codes_mapping( # noqa: C901
|
|||
|
||||
def normalize_paths(
|
||||
paths: Sequence[str], parent: str = os.curdir
|
||||
) -> List[str]:
|
||||
) -> list[str]:
|
||||
"""Normalize a list of paths relative to a parent directory.
|
||||
|
||||
:returns:
|
||||
|
|
@ -201,12 +197,12 @@ def stdin_get_value() -> str:
|
|||
return stdin_value.decode("utf-8")
|
||||
|
||||
|
||||
def stdin_get_lines() -> List[str]:
|
||||
def stdin_get_lines() -> list[str]:
|
||||
"""Return lines of stdin split according to file splitting."""
|
||||
return list(io.StringIO(stdin_get_value()))
|
||||
|
||||
|
||||
def parse_unified_diff(diff: Optional[str] = None) -> Dict[str, Set[int]]:
|
||||
def parse_unified_diff(diff: str | None = None) -> dict[str, set[int]]:
|
||||
"""Parse the unified diff passed on stdin.
|
||||
|
||||
:returns:
|
||||
|
|
@ -218,7 +214,7 @@ def parse_unified_diff(diff: Optional[str] = None) -> Dict[str, Set[int]]:
|
|||
|
||||
number_of_rows = None
|
||||
current_path = None
|
||||
parsed_paths: Dict[str, Set[int]] = collections.defaultdict(set)
|
||||
parsed_paths: dict[str, set[int]] = collections.defaultdict(set)
|
||||
for line in diff.splitlines():
|
||||
if number_of_rows:
|
||||
if not line or line[0] != "-":
|
||||
|
|
@ -271,7 +267,7 @@ def parse_unified_diff(diff: Optional[str] = None) -> Dict[str, Set[int]]:
|
|||
return parsed_paths
|
||||
|
||||
|
||||
def is_using_stdin(paths: List[str]) -> bool:
|
||||
def is_using_stdin(paths: list[str]) -> bool:
|
||||
"""Determine if we're going to read from stdin.
|
||||
|
||||
:param paths:
|
||||
|
|
|
|||
|
|
@ -1,12 +1,11 @@
|
|||
"""Contains the Violation error class used internally."""
|
||||
from __future__ import annotations
|
||||
|
||||
import functools
|
||||
import linecache
|
||||
import logging
|
||||
from typing import Dict
|
||||
from typing import Match
|
||||
from typing import NamedTuple
|
||||
from typing import Optional
|
||||
from typing import Set
|
||||
|
||||
from flake8 import defaults
|
||||
from flake8 import utils
|
||||
|
|
@ -16,7 +15,7 @@ LOG = logging.getLogger(__name__)
|
|||
|
||||
|
||||
@functools.lru_cache(maxsize=512)
|
||||
def _find_noqa(physical_line: str) -> Optional[Match[str]]:
|
||||
def _find_noqa(physical_line: str) -> Match[str] | None:
|
||||
return defaults.NOQA_INLINE_REGEXP.search(physical_line)
|
||||
|
||||
|
||||
|
|
@ -28,7 +27,7 @@ class Violation(NamedTuple):
|
|||
line_number: int
|
||||
column_number: int
|
||||
text: str
|
||||
physical_line: Optional[str]
|
||||
physical_line: str | None
|
||||
|
||||
def is_inline_ignored(self, disable_noqa: bool) -> bool:
|
||||
"""Determine if a comment has been added to ignore this line.
|
||||
|
|
@ -69,7 +68,7 @@ class Violation(NamedTuple):
|
|||
)
|
||||
return False
|
||||
|
||||
def is_in(self, diff: Dict[str, Set[int]]) -> bool:
|
||||
def is_in(self, diff: dict[str, set[int]]) -> bool:
|
||||
"""Determine if the violation is included in a diff's line ranges.
|
||||
|
||||
This function relies on the parsed data added via
|
||||
|
|
|
|||
|
|
@ -1 +1,2 @@
|
|||
"""This is here because mypy doesn't understand PEP 420."""
|
||||
from __future__ import annotations
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
"""Test configuration for py.test."""
|
||||
from __future__ import annotations
|
||||
|
||||
import sys
|
||||
|
||||
import flake8
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
"""Module that is off sys.path by default, for testing local-plugin-paths."""
|
||||
from __future__ import annotations
|
||||
|
||||
|
||||
class ExtensionTestPlugin2:
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
"""Test aggregation of config files and command-line options."""
|
||||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
|
||||
import pytest
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
"""Integration tests for the legacy api."""
|
||||
from __future__ import annotations
|
||||
|
||||
from flake8.api import legacy
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
"""Integration tests for the checker submodule."""
|
||||
from __future__ import annotations
|
||||
|
||||
import sys
|
||||
from unittest import mock
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
"""Integration tests for the main entrypoint of flake8."""
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
"""Integration tests for plugin loading."""
|
||||
from __future__ import annotations
|
||||
|
||||
import pytest
|
||||
|
||||
from flake8.main.cli import main
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
"""Shared fixtures between unit tests."""
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
|
||||
import pytest
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
from __future__ import annotations
|
||||
|
||||
import configparser
|
||||
import sys
|
||||
from unittest import mock
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
from __future__ import annotations
|
||||
|
||||
import importlib.machinery
|
||||
import importlib.util
|
||||
import os.path
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
|
||||
import pytest
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
"""Tests for the Application class."""
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
|
||||
import pytest
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
"""Tests for the BaseFormatter object."""
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import sys
|
||||
from unittest import mock
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
"""Tests for the Manager object for FileCheckers."""
|
||||
from __future__ import annotations
|
||||
|
||||
import errno
|
||||
import multiprocessing
|
||||
from unittest import mock
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
from __future__ import annotations
|
||||
|
||||
from unittest import mock
|
||||
|
||||
from flake8._compat import importlib_metadata
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
"""Tests for the flake8.style_guide.DecisionEngine class."""
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
|
||||
import pytest
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
from __future__ import annotations
|
||||
|
||||
import os.path
|
||||
|
||||
import pytest
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
"""Tests for the flake8.exceptions module."""
|
||||
from __future__ import annotations
|
||||
|
||||
import pickle
|
||||
|
||||
import pytest
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
"""Unit tests for the FileChecker class."""
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
from unittest import mock
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
"""Tests for the FileProcessor class."""
|
||||
from __future__ import annotations
|
||||
|
||||
import ast
|
||||
import tokenize
|
||||
from unittest import mock
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
"""Tests for the FilenameOnly formatter object."""
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
|
||||
from flake8.formatting import default
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
"""Tests for Flake8's legacy API."""
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import configparser
|
||||
import os.path
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
from __future__ import annotations
|
||||
|
||||
from flake8.main import options
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
"""Tests for the Nothing formatter obbject."""
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
|
||||
from flake8.formatting import default
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
"""Unit tests for flake8.options.manager.Option."""
|
||||
from __future__ import annotations
|
||||
|
||||
import functools
|
||||
from unittest import mock
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
"""Unit tests for flake.options.manager.OptionManager."""
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import os
|
||||
from unittest import mock
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
from __future__ import annotations
|
||||
|
||||
import configparser
|
||||
import os.path
|
||||
from unittest import mock
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
"""Tests of pyflakes monkey patches."""
|
||||
from __future__ import annotations
|
||||
|
||||
import ast
|
||||
|
||||
import pyflakes
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
"""Tests for the statistics module in Flake8."""
|
||||
from __future__ import annotations
|
||||
|
||||
import pytest
|
||||
|
||||
from flake8 import statistics as stats
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
"""Tests for the flake8.style_guide.StyleGuide class."""
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
from unittest import mock
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
"""Tests for flake8's utils module."""
|
||||
from __future__ import annotations
|
||||
|
||||
import io
|
||||
import logging
|
||||
import os
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
"""Tests for the flake8.violation.Violation class."""
|
||||
from __future__ import annotations
|
||||
|
||||
from unittest import mock
|
||||
|
||||
import pytest
|
||||
|
|
|
|||
2
tox.ini
2
tox.ini
|
|
@ -1,6 +1,6 @@
|
|||
[tox]
|
||||
minversion=2.3.1
|
||||
envlist = py36,py37,py38,flake8,linters,docs
|
||||
envlist = py37,py38,flake8,linters,docs
|
||||
|
||||
[testenv]
|
||||
deps =
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue