mirror of
https://github.com/PyCQA/flake8.git
synced 2026-03-29 02:26:54 +00:00
py39+
This commit is contained in:
parent
e492aeb385
commit
9d55ccdb72
22 changed files with 64 additions and 78 deletions
10
.github/workflows/main.yml
vendored
10
.github/workflows/main.yml
vendored
|
|
@ -15,9 +15,6 @@ jobs:
|
|||
- os: ubuntu-latest
|
||||
python: pypy-3.9
|
||||
toxenv: py
|
||||
- os: ubuntu-latest
|
||||
python: 3.8
|
||||
toxenv: py
|
||||
- os: ubuntu-latest
|
||||
python: 3.9
|
||||
toxenv: py
|
||||
|
|
@ -28,11 +25,14 @@ jobs:
|
|||
python: '3.11'
|
||||
toxenv: py
|
||||
- os: ubuntu-latest
|
||||
python: '3.12-dev'
|
||||
python: '3.12'
|
||||
toxenv: py
|
||||
- os: ubuntu-latest
|
||||
python: '3.13'
|
||||
toxenv: py
|
||||
# windows
|
||||
- os: windows-latest
|
||||
python: 3.8
|
||||
python: 3.9
|
||||
toxenv: py
|
||||
# misc
|
||||
- os: ubuntu-latest
|
||||
|
|
|
|||
|
|
@ -12,19 +12,19 @@ repos:
|
|||
hooks:
|
||||
- id: setup-cfg-fmt
|
||||
- repo: https://github.com/asottile/reorder-python-imports
|
||||
rev: v3.12.0
|
||||
rev: v3.14.0
|
||||
hooks:
|
||||
- id: reorder-python-imports
|
||||
args: [
|
||||
--application-directories, '.:src',
|
||||
--py38-plus,
|
||||
--py39-plus,
|
||||
--add-import, 'from __future__ import annotations',
|
||||
]
|
||||
- repo: https://github.com/asottile/pyupgrade
|
||||
rev: v3.15.0
|
||||
rev: v3.19.1
|
||||
hooks:
|
||||
- id: pyupgrade
|
||||
args: [--py38-plus]
|
||||
args: [--py39-plus]
|
||||
- repo: https://github.com/psf/black
|
||||
rev: 23.12.1
|
||||
hooks:
|
||||
|
|
@ -35,7 +35,7 @@ repos:
|
|||
hooks:
|
||||
- id: flake8
|
||||
- repo: https://github.com/pre-commit/mirrors-mypy
|
||||
rev: v1.8.0
|
||||
rev: v1.15.0
|
||||
hooks:
|
||||
- id: mypy
|
||||
exclude: ^(docs/|example-plugin/)
|
||||
|
|
|
|||
|
|
@ -3,9 +3,9 @@ from __future__ import annotations
|
|||
|
||||
import inspect
|
||||
import os.path
|
||||
from collections.abc import Generator
|
||||
from typing import Any
|
||||
from typing import Callable
|
||||
from typing import Generator
|
||||
from typing import NamedTuple
|
||||
|
||||
import pycodestyle
|
||||
|
|
@ -42,7 +42,7 @@ class Call(NamedTuple):
|
|||
return cls(func.__name__, inspect.isgeneratorfunction(func), params)
|
||||
|
||||
|
||||
def lines() -> Generator[str, None, None]:
|
||||
def lines() -> Generator[str]:
|
||||
logical = []
|
||||
physical = []
|
||||
|
||||
|
|
@ -58,8 +58,8 @@ def lines() -> Generator[str, None, None]:
|
|||
yield "# fmt: off"
|
||||
yield "from __future__ import annotations"
|
||||
yield ""
|
||||
yield "from collections.abc import Generator"
|
||||
yield "from typing import Any"
|
||||
yield "from typing import Generator"
|
||||
yield ""
|
||||
imports = sorted(call.name for call in logical + physical)
|
||||
for name in imports:
|
||||
|
|
@ -71,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]]:"
|
||||
yield ' """Run pycodestyle logical checks."""'
|
||||
for call in sorted(logical):
|
||||
yield call.to_src()
|
||||
|
|
@ -82,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]]:"
|
||||
yield ' """Run pycodestyle physical checks."""'
|
||||
for call in sorted(physical):
|
||||
yield call.to_src()
|
||||
|
|
|
|||
|
|
@ -81,9 +81,9 @@ for users.
|
|||
|
||||
Before releasing, the following tox test environments must pass:
|
||||
|
||||
- Python 3.8 (a.k.a., ``tox -e py38``)
|
||||
- Python 3.9 (a.k.a., ``tox -e py39``)
|
||||
|
||||
- Python 3.12 (a.k.a., ``tox -e py312``)
|
||||
- Python 3.13 (a.k.a., ``tox -e py313``)
|
||||
|
||||
- PyPy 3 (a.k.a., ``tox -e pypy3``)
|
||||
|
||||
|
|
|
|||
|
|
@ -14,25 +14,25 @@ like so:
|
|||
|
||||
Where you simply allow the shell running in your terminal to locate |Flake8|.
|
||||
In some cases, though, you may have installed |Flake8| for multiple versions
|
||||
of Python (e.g., Python 3.8 and Python 3.9) and you need to call a specific
|
||||
of Python (e.g., Python 3.13 and Python 3.14) and you need to call a specific
|
||||
version. In that case, you will have much better results using:
|
||||
|
||||
.. prompt:: bash
|
||||
|
||||
python3.8 -m flake8
|
||||
python3.13 -m flake8
|
||||
|
||||
Or
|
||||
|
||||
.. prompt:: bash
|
||||
|
||||
python3.9 -m flake8
|
||||
python3.14 -m flake8
|
||||
|
||||
Since that will tell the correct version of Python to run |Flake8|.
|
||||
|
||||
.. note::
|
||||
|
||||
Installing |Flake8| once will not install it on both Python 3.8 and
|
||||
Python 3.9. It will only install it for the version of Python that
|
||||
Installing |Flake8| once will not install it on both Python 3.13 and
|
||||
Python 3.14. It will only install it for the version of Python that
|
||||
is running pip.
|
||||
|
||||
It is also possible to specify command-line options directly to |Flake8|:
|
||||
|
|
|
|||
|
|
@ -23,8 +23,6 @@ setuptools.setup(
|
|||
"License :: OSI Approved :: MIT License",
|
||||
"Programming Language :: Python",
|
||||
"Programming Language :: Python :: 3",
|
||||
"Programming Language :: Python :: 3.8",
|
||||
"Programming Language :: Python :: 3.9",
|
||||
"Topic :: Software Development :: Libraries :: Python Modules",
|
||||
"Topic :: Software Development :: Quality Assurance",
|
||||
],
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ install_requires =
|
|||
mccabe>=0.7.0,<0.8.0
|
||||
pycodestyle>=2.12.0,<2.13.0
|
||||
pyflakes>=3.2.0,<3.3.0
|
||||
python_requires = >=3.8.1
|
||||
python_requires = >=3.9
|
||||
package_dir =
|
||||
=src
|
||||
|
||||
|
|
|
|||
|
|
@ -9,12 +9,10 @@ import multiprocessing.pool
|
|||
import operator
|
||||
import signal
|
||||
import tokenize
|
||||
from collections.abc import Generator
|
||||
from collections.abc import Sequence
|
||||
from typing import Any
|
||||
from typing import Generator
|
||||
from typing import List
|
||||
from typing import Optional
|
||||
from typing import Sequence
|
||||
from typing import Tuple
|
||||
|
||||
from flake8 import defaults
|
||||
from flake8 import exceptions
|
||||
|
|
@ -27,7 +25,7 @@ from flake8.plugins.finder import Checkers
|
|||
from flake8.plugins.finder import LoadedPlugin
|
||||
from flake8.style_guide import StyleGuideManager
|
||||
|
||||
Results = List[Tuple[str, int, int, str, Optional[str]]]
|
||||
Results = list[tuple[str, int, int, str, Optional[str]]]
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
|
@ -53,7 +51,7 @@ _mp_options: argparse.Namespace
|
|||
@contextlib.contextmanager
|
||||
def _mp_prefork(
|
||||
plugins: Checkers, options: argparse.Namespace
|
||||
) -> Generator[None, None, None]:
|
||||
) -> Generator[None]:
|
||||
# we can save significant startup work w/ `fork` multiprocessing
|
||||
global _mp_plugins, _mp_options
|
||||
_mp_plugins, _mp_options = plugins, options
|
||||
|
|
|
|||
|
|
@ -3,9 +3,9 @@ from __future__ import annotations
|
|||
|
||||
import logging
|
||||
import os.path
|
||||
from collections.abc import Generator
|
||||
from collections.abc import Sequence
|
||||
from typing import Callable
|
||||
from typing import Generator
|
||||
from typing import Sequence
|
||||
|
||||
from flake8 import utils
|
||||
|
||||
|
|
@ -16,7 +16,7 @@ def _filenames_from(
|
|||
arg: str,
|
||||
*,
|
||||
predicate: Callable[[str], bool],
|
||||
) -> Generator[str, None, None]:
|
||||
) -> Generator[str]:
|
||||
"""Generate filenames from an argument.
|
||||
|
||||
:param arg:
|
||||
|
|
@ -55,7 +55,7 @@ def expand_paths(
|
|||
stdin_display_name: str,
|
||||
filename_patterns: Sequence[str],
|
||||
exclude: Sequence[str],
|
||||
) -> Generator[str, None, None]:
|
||||
) -> Generator[str]:
|
||||
"""Expand out ``paths`` from commandline to the lintable files."""
|
||||
if not paths:
|
||||
paths = ["."]
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import argparse
|
|||
import json
|
||||
import logging
|
||||
import time
|
||||
from typing import Sequence
|
||||
from collections.abc import Sequence
|
||||
|
||||
import flake8
|
||||
from flake8 import checker
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
from __future__ import annotations
|
||||
|
||||
import sys
|
||||
from typing import Sequence
|
||||
from collections.abc import Sequence
|
||||
|
||||
from flake8.main import application
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ from __future__ import annotations
|
|||
import argparse
|
||||
import configparser
|
||||
import logging
|
||||
from typing import Sequence
|
||||
from collections.abc import Sequence
|
||||
|
||||
from flake8.options import config
|
||||
from flake8.options.manager import OptionManager
|
||||
|
|
|
|||
|
|
@ -5,9 +5,9 @@ import argparse
|
|||
import enum
|
||||
import functools
|
||||
import logging
|
||||
from collections.abc import Sequence
|
||||
from typing import Any
|
||||
from typing import Callable
|
||||
from typing import Sequence
|
||||
|
||||
from flake8 import utils
|
||||
from flake8.plugins.finder import Plugins
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
from typing import Sequence
|
||||
from collections.abc import Sequence
|
||||
|
||||
import flake8
|
||||
from flake8.main import options
|
||||
|
|
|
|||
|
|
@ -7,9 +7,9 @@ import inspect
|
|||
import itertools
|
||||
import logging
|
||||
import sys
|
||||
from collections.abc import Generator
|
||||
from collections.abc import Iterable
|
||||
from typing import Any
|
||||
from typing import Generator
|
||||
from typing import Iterable
|
||||
from typing import NamedTuple
|
||||
|
||||
from flake8 import utils
|
||||
|
|
@ -68,7 +68,7 @@ class Plugins(NamedTuple):
|
|||
reporters: dict[str, LoadedPlugin]
|
||||
disabled: list[LoadedPlugin]
|
||||
|
||||
def all_plugins(self) -> Generator[LoadedPlugin, None, None]:
|
||||
def all_plugins(self) -> Generator[LoadedPlugin]:
|
||||
"""Return an iterator over all :class:`LoadedPlugin`s."""
|
||||
yield from self.checkers.tree
|
||||
yield from self.checkers.logical_line
|
||||
|
|
@ -151,7 +151,7 @@ def _flake8_plugins(
|
|||
eps: Iterable[importlib.metadata.EntryPoint],
|
||||
name: str,
|
||||
version: str,
|
||||
) -> Generator[Plugin, None, None]:
|
||||
) -> Generator[Plugin]:
|
||||
pyflakes_meta = importlib.metadata.distribution("pyflakes").metadata
|
||||
pycodestyle_meta = importlib.metadata.distribution("pycodestyle").metadata
|
||||
|
||||
|
|
@ -173,7 +173,7 @@ def _flake8_plugins(
|
|||
yield Plugin(name, version, ep)
|
||||
|
||||
|
||||
def _find_importlib_plugins() -> Generator[Plugin, None, None]:
|
||||
def _find_importlib_plugins() -> Generator[Plugin]:
|
||||
# some misconfigured pythons (RHEL) have things on `sys.path` twice
|
||||
seen = set()
|
||||
for dist in importlib.metadata.distributions():
|
||||
|
|
@ -212,7 +212,7 @@ def _find_importlib_plugins() -> Generator[Plugin, None, None]:
|
|||
|
||||
def _find_local_plugins(
|
||||
cfg: configparser.RawConfigParser,
|
||||
) -> Generator[Plugin, None, None]:
|
||||
) -> Generator[Plugin]:
|
||||
for plugin_type in ("extension", "report"):
|
||||
group = f"flake8.{plugin_type}"
|
||||
for plugin_s in utils.parse_comma_separated_list(
|
||||
|
|
|
|||
|
|
@ -2,8 +2,8 @@
|
|||
# fmt: off
|
||||
from __future__ import annotations
|
||||
|
||||
from collections.abc import Generator
|
||||
from typing import Any
|
||||
from typing import Generator
|
||||
|
||||
from pycodestyle import ambiguous_identifier as _ambiguous_identifier
|
||||
from pycodestyle import bare_except as _bare_except
|
||||
|
|
@ -55,7 +55,7 @@ def pycodestyle_logical(
|
|||
previous_unindented_logical_line: Any,
|
||||
tokens: Any,
|
||||
verbose: Any,
|
||||
) -> Generator[tuple[int, str], None, None]:
|
||||
) -> Generator[tuple[int, str]]:
|
||||
"""Run pycodestyle logical checks."""
|
||||
yield from _ambiguous_identifier(logical_line, tokens)
|
||||
yield from _bare_except(logical_line, noqa)
|
||||
|
|
@ -93,7 +93,7 @@ def pycodestyle_physical(
|
|||
noqa: Any,
|
||||
physical_line: Any,
|
||||
total_lines: Any,
|
||||
) -> Generator[tuple[int, str], None, None]:
|
||||
) -> Generator[tuple[int, str]]:
|
||||
"""Run pycodestyle physical checks."""
|
||||
ret = _maximum_line_length(physical_line, max_line_length, multiline, line_number, noqa) # noqa: E501
|
||||
if ret is not None:
|
||||
|
|
|
|||
|
|
@ -4,8 +4,8 @@ from __future__ import annotations
|
|||
import argparse
|
||||
import ast
|
||||
import logging
|
||||
from collections.abc import Generator
|
||||
from typing import Any
|
||||
from typing import Generator
|
||||
|
||||
import pyflakes.checker
|
||||
|
||||
|
|
@ -97,7 +97,7 @@ class FlakesChecker(pyflakes.checker.Checker):
|
|||
cls.builtIns = cls.builtIns.union(options.builtins)
|
||||
cls.with_doctest = options.doctests
|
||||
|
||||
def run(self) -> Generator[tuple[int, int, str, type[Any]], None, None]:
|
||||
def run(self) -> Generator[tuple[int, int, str, type[Any]]]:
|
||||
"""Run the plugin."""
|
||||
for message in self.messages:
|
||||
col = getattr(message, "col", 0)
|
||||
|
|
|
|||
|
|
@ -6,10 +6,8 @@ import ast
|
|||
import functools
|
||||
import logging
|
||||
import tokenize
|
||||
from collections.abc import Generator
|
||||
from typing import Any
|
||||
from typing import Generator
|
||||
from typing import List
|
||||
from typing import Tuple
|
||||
|
||||
from flake8 import defaults
|
||||
from flake8 import utils
|
||||
|
|
@ -24,8 +22,8 @@ SKIP_TOKENS = frozenset(
|
|||
[tokenize.NL, tokenize.NEWLINE, tokenize.INDENT, tokenize.DEDENT]
|
||||
)
|
||||
|
||||
_LogicalMapping = List[Tuple[int, Tuple[int, int]]]
|
||||
_Logical = Tuple[List[str], List[str], _LogicalMapping]
|
||||
_LogicalMapping = list[tuple[int, tuple[int, int]]]
|
||||
_Logical = tuple[list[str], list[str], _LogicalMapping]
|
||||
|
||||
|
||||
class FileProcessor:
|
||||
|
|
@ -127,9 +125,7 @@ class FileProcessor:
|
|||
"""Signal the beginning of an fstring."""
|
||||
self._fstring_start = lineno
|
||||
|
||||
def multiline_string(
|
||||
self, token: tokenize.TokenInfo
|
||||
) -> Generator[str, None, None]:
|
||||
def multiline_string(self, token: tokenize.TokenInfo) -> Generator[str]:
|
||||
"""Iterate through the lines of a multiline string."""
|
||||
if token.type == FSTRING_END: # pragma: >=3.12 cover
|
||||
start = self._fstring_start
|
||||
|
|
@ -210,7 +206,7 @@ class FileProcessor:
|
|||
brace_offset = text.count("{") + text.count("}")
|
||||
text = "x" * (len(text) + brace_offset)
|
||||
end = (end[0], end[1] + brace_offset)
|
||||
if previous_row:
|
||||
if previous_row is not None and previous_column is not None:
|
||||
(start_row, start_column) = start
|
||||
if previous_row != start_row:
|
||||
row_index = previous_row - 1
|
||||
|
|
@ -263,7 +259,7 @@ class FileProcessor:
|
|||
)
|
||||
return ret
|
||||
|
||||
def generate_tokens(self) -> Generator[tokenize.TokenInfo, None, None]:
|
||||
def generate_tokens(self) -> Generator[tokenize.TokenInfo]:
|
||||
"""Tokenize the file and yield the tokens."""
|
||||
for token in tokenize.generate_tokens(self.next_line):
|
||||
if token[2][0] > self.total_lines:
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
"""Statistic collection logic for Flake8."""
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Generator
|
||||
from collections.abc import Generator
|
||||
from typing import NamedTuple
|
||||
|
||||
from flake8.violation import Violation
|
||||
|
|
@ -36,7 +36,7 @@ class Statistics:
|
|||
|
||||
def statistics_for(
|
||||
self, prefix: str, filename: str | None = None
|
||||
) -> Generator[Statistic, None, None]:
|
||||
) -> Generator[Statistic]:
|
||||
"""Generate statistics for the prefix and filename.
|
||||
|
||||
If you have a :class:`Statistics` object that has recorded errors,
|
||||
|
|
|
|||
|
|
@ -7,8 +7,8 @@ import copy
|
|||
import enum
|
||||
import functools
|
||||
import logging
|
||||
from typing import Generator
|
||||
from typing import Sequence
|
||||
from collections.abc import Generator
|
||||
from collections.abc import Sequence
|
||||
|
||||
from flake8 import defaults
|
||||
from flake8 import statistics
|
||||
|
|
@ -225,13 +225,11 @@ class StyleGuideManager:
|
|||
*self.populate_style_guides_with(options),
|
||||
]
|
||||
|
||||
self.style_guide_for = functools.lru_cache(maxsize=None)(
|
||||
self._style_guide_for
|
||||
)
|
||||
self.style_guide_for = functools.cache(self._style_guide_for)
|
||||
|
||||
def populate_style_guides_with(
|
||||
self, options: argparse.Namespace
|
||||
) -> Generator[StyleGuide, None, None]:
|
||||
) -> Generator[StyleGuide]:
|
||||
"""Generate style guides from the per-file-ignores option.
|
||||
|
||||
:param options:
|
||||
|
|
@ -253,9 +251,7 @@ class StyleGuideManager:
|
|||
)
|
||||
|
||||
@contextlib.contextmanager
|
||||
def processing_file(
|
||||
self, filename: str
|
||||
) -> Generator[StyleGuide, None, None]:
|
||||
def processing_file(self, filename: str) -> Generator[StyleGuide]:
|
||||
"""Record the fact that we're processing the file's results."""
|
||||
guide = self.style_guide_for(filename)
|
||||
with guide.processing_file(filename):
|
||||
|
|
@ -338,9 +334,7 @@ class StyleGuide:
|
|||
)
|
||||
|
||||
@contextlib.contextmanager
|
||||
def processing_file(
|
||||
self, filename: str
|
||||
) -> Generator[StyleGuide, None, None]:
|
||||
def processing_file(self, filename: str) -> Generator[StyleGuide]:
|
||||
"""Record the fact that we're processing the file's results."""
|
||||
self.formatter.beginning(filename)
|
||||
yield self
|
||||
|
|
|
|||
|
|
@ -11,9 +11,9 @@ import re
|
|||
import sys
|
||||
import textwrap
|
||||
import tokenize
|
||||
from collections.abc import Sequence
|
||||
from re import Pattern
|
||||
from typing import NamedTuple
|
||||
from typing import Pattern
|
||||
from typing import Sequence
|
||||
|
||||
from flake8 import exceptions
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ from __future__ import annotations
|
|||
import functools
|
||||
import linecache
|
||||
import logging
|
||||
from typing import Match
|
||||
from re import Match
|
||||
from typing import NamedTuple
|
||||
|
||||
from flake8 import defaults
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue