Skip to content

py39+ #1973

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Mar 29, 2025
Merged

py39+ #1973

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down
10 changes: 5 additions & 5 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand All @@ -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/)
10 changes: 5 additions & 5 deletions bin/gen-pycodestyle-plugin
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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 = []

Expand All @@ -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:
Expand All @@ -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()
Expand All @@ -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()
Expand Down
4 changes: 2 additions & 2 deletions docs/source/internal/releases.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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``)

Expand Down
10 changes: 5 additions & 5 deletions docs/source/user/invocation.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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|:
Expand Down
2 changes: 0 additions & 2 deletions example-plugin/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,6 @@
"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",
],
Expand Down
2 changes: 1 addition & 1 deletion setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
10 changes: 4 additions & 6 deletions src/flake8/checker.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,10 @@
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
Expand All @@ -27,7 +25,7 @@
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__)

Expand All @@ -53,7 +51,7 @@
@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
Expand Down
8 changes: 4 additions & 4 deletions src/flake8/discover_files.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@

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

Expand All @@ -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:
Expand Down Expand Up @@ -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 = ["."]
Expand Down
2 changes: 1 addition & 1 deletion src/flake8/main/application.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import json
import logging
import time
from typing import Sequence
from collections.abc import Sequence

import flake8
from flake8 import checker
Expand Down
2 changes: 1 addition & 1 deletion src/flake8/main/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from __future__ import annotations

import sys
from typing import Sequence
from collections.abc import Sequence

from flake8.main import application

Expand Down
2 changes: 1 addition & 1 deletion src/flake8/options/aggregator.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
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
Expand Down
2 changes: 1 addition & 1 deletion src/flake8/options/manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
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
Expand Down
2 changes: 1 addition & 1 deletion src/flake8/options/parse_args.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
12 changes: 6 additions & 6 deletions src/flake8/plugins/finder.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@
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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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

Expand All @@ -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():
Expand Down Expand Up @@ -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(
Expand Down
6 changes: 3 additions & 3 deletions src/flake8/plugins/pycodestyle.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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:
Expand Down
4 changes: 2 additions & 2 deletions src/flake8/plugins/pyflakes.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
import argparse
import ast
import logging
from collections.abc import Generator
from typing import Any
from typing import Generator

import pyflakes.checker

Expand Down Expand Up @@ -97,7 +97,7 @@ def parse_options(cls, options: argparse.Namespace) -> None:
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)
Expand Down
Loading