diff --git a/pyproject.toml b/pyproject.toml index 32c2bf5b350c..4819ff05a341 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -45,6 +45,7 @@ select = [ "I", # isort "N", # pep8-naming "PGH", # pygrep-hooks + "PLR", # Pylint Refactor "RUF", # Ruff-specific and unused-noqa "TRY", # tryceratops "UP", # pyupgrade @@ -117,6 +118,10 @@ ignore = [ # Used for direct, non-subclass type comparison, for example: `type(val) is str` # see https://github.com/astral-sh/ruff/issues/6465 "E721", # Do not compare types, use `isinstance()` + # Leave the size and complexity of tests to human interpretation + "PLR09", # Too many ... + # Too many magic number "2" that are preferable inline. https://github.com/astral-sh/ruff/issues/10009 + "PLR2004", # Magic value used in comparison, consider replacing `{value}` with a constant variable # Mostly from scripts and tests, it's ok to have messages passed directly to exceptions "TRY003", # Avoid specifying long messages outside the exception class # Slower and more verbose https://github.com/astral-sh/ruff/issues/7871 diff --git a/scripts/create_baseline_stubs.py b/scripts/create_baseline_stubs.py index 46de29b026c7..3766266adc91 100755 --- a/scripts/create_baseline_stubs.py +++ b/scripts/create_baseline_stubs.py @@ -18,6 +18,7 @@ import subprocess import sys import urllib.parse +from http import HTTPStatus from importlib.metadata import distribution import aiohttp @@ -72,7 +73,7 @@ def run_ruff(stub_dir: str) -> None: async def get_project_urls_from_pypi(project: str, session: aiohttp.ClientSession) -> dict[str, str]: pypi_root = f"https://pypi.org/pypi/{urllib.parse.quote(project)}" async with session.get(f"{pypi_root}/json") as response: - if response.status != 200: + if response.status != HTTPStatus.OK: return {} j: dict[str, dict[str, dict[str, str]]] j = await response.json() @@ -107,7 +108,7 @@ async def get_upstream_repo_url(project: str) -> str | None: # truncate to https://site.com/user/repo upstream_repo_url = "/".join(url.split("/")[:5]) async with session.get(upstream_repo_url) as response: - if response.status == 200: + if response.status == HTTPStatus.OK: return upstream_repo_url return None diff --git a/scripts/stubsabot.py b/scripts/stubsabot.py index f121bed5f5f0..3e755ca2d5d4 100755 --- a/scripts/stubsabot.py +++ b/scripts/stubsabot.py @@ -308,7 +308,7 @@ async def get_github_repo_info(session: aiohttp.ClientSession, stub_info: StubMe assert len(Path(url_path).parts) == 2 github_tags_info_url = f"https://api.github.com/repos/{url_path}/tags" async with session.get(github_tags_info_url, headers=get_github_api_headers()) as response: - if response.status == 200: + if response.status == HTTPStatus.OK: tags: list[dict[str, Any]] = await response.json() assert isinstance(tags, list) return GitHubInfo(repo_path=url_path, tags=tags) diff --git a/stdlib/asyncio/__init__.pyi b/stdlib/asyncio/__init__.pyi index 7c3ac6ede4fe..3f3bc4a10a6c 100644 --- a/stdlib/asyncio/__init__.pyi +++ b/stdlib/asyncio/__init__.pyi @@ -1,3 +1,5 @@ +# ruff: noqa: PLR5501 # This condition is so big, it's clearer to keep to platform condition in two blocks +# Can't NOQA on a specific line: https://github.com/plinss/flake8-noqa/issues/22 import sys from collections.abc import Awaitable, Coroutine, Generator from typing import Any, TypeVar diff --git a/stdlib/importlib/readers.pyi b/stdlib/importlib/readers.pyi index 41d7af966d58..8f6074a16738 100644 --- a/stdlib/importlib/readers.pyi +++ b/stdlib/importlib/readers.pyi @@ -12,9 +12,9 @@ from typing import Literal, NoReturn, TypeVar from typing_extensions import Never if sys.version_info >= (3, 11): - import importlib.resources.abc as abc + from importlib.resources import abc else: - import importlib.abc as abc + from importlib import abc if sys.version_info >= (3, 10): if sys.version_info >= (3, 11): diff --git a/stdlib/mmap.pyi b/stdlib/mmap.pyi index c9b8358cde6c..bd9e7361b6e7 100644 --- a/stdlib/mmap.pyi +++ b/stdlib/mmap.pyi @@ -33,23 +33,22 @@ PAGESIZE: int class mmap: if sys.platform == "win32": def __init__(self, fileno: int, length: int, tagname: str | None = ..., access: int = ..., offset: int = ...) -> None: ... + elif sys.version_info >= (3, 13): + def __new__( + cls, + fileno: int, + length: int, + flags: int = ..., + prot: int = ..., + access: int = ..., + offset: int = ..., + *, + trackfd: bool = True, + ) -> Self: ... else: - if sys.version_info >= (3, 13): - def __new__( - cls, - fileno: int, - length: int, - flags: int = ..., - prot: int = ..., - access: int = ..., - offset: int = ..., - *, - trackfd: bool = True, - ) -> Self: ... - else: - def __new__( - cls, fileno: int, length: int, flags: int = ..., prot: int = ..., access: int = ..., offset: int = ... - ) -> Self: ... + def __new__( + cls, fileno: int, length: int, flags: int = ..., prot: int = ..., access: int = ..., offset: int = ... + ) -> Self: ... def close(self) -> None: ... def flush(self, offset: int = ..., size: int = ...) -> None: ... diff --git a/stubs/gevent/gevent/libev/corecext.pyi b/stubs/gevent/gevent/libev/corecext.pyi index 994793ee8a25..35a46bbf3655 100644 --- a/stubs/gevent/gevent/libev/corecext.pyi +++ b/stubs/gevent/gevent/libev/corecext.pyi @@ -5,9 +5,9 @@ from types import TracebackType from typing import Any from typing_extensions import ParamSpec -import gevent.libev.watcher as watcher from gevent._ffi.loop import _ErrorHandler from gevent._types import _Callback +from gevent.libev import watcher # this c extension is only available on posix if sys.platform != "win32": diff --git a/stubs/gevent/gevent/libev/corecffi.pyi b/stubs/gevent/gevent/libev/corecffi.pyi index 4dc59a997f30..e814fb9b90b3 100644 --- a/stubs/gevent/gevent/libev/corecffi.pyi +++ b/stubs/gevent/gevent/libev/corecffi.pyi @@ -2,8 +2,8 @@ import sys from _typeshed import FileDescriptor from collections.abc import Sequence -import gevent.libev.watcher as watcher from gevent._ffi.loop import AbstractLoop +from gevent.libev import watcher def get_version() -> str: ... def get_header_version() -> str: ... diff --git a/stubs/gevent/gevent/libuv/loop.pyi b/stubs/gevent/gevent/libuv/loop.pyi index e5d539acb3c0..950b82118375 100644 --- a/stubs/gevent/gevent/libuv/loop.pyi +++ b/stubs/gevent/gevent/libuv/loop.pyi @@ -2,9 +2,9 @@ import sys from _typeshed import FileDescriptor from typing import NamedTuple -import gevent.libuv.watcher as watcher from gevent._ffi.loop import AbstractLoop from gevent._types import _IoWatcher +from gevent.libuv import watcher def get_version() -> str: ... def get_header_version() -> str: ... diff --git a/tests/runtests.py b/tests/runtests.py index 1c5ba0c18ab9..2520ea015825 100755 --- a/tests/runtests.py +++ b/tests/runtests.py @@ -104,19 +104,18 @@ def main() -> None: if folder == "stdlib": print("\nRunning stubtest...") stubtest_result = subprocess.run([sys.executable, "tests/stubtest_stdlib.py", stub]) + elif run_stubtest: + print("\nRunning stubtest...") + stubtest_result = subprocess.run([sys.executable, "tests/stubtest_third_party.py", stub]) else: - if run_stubtest: - print("\nRunning stubtest...") - stubtest_result = subprocess.run([sys.executable, "tests/stubtest_third_party.py", stub]) - else: - print( - colored( - f"\nSkipping stubtest for {stub!r}..." - + "\nNOTE: Running third-party stubtest involves downloading and executing arbitrary code from PyPI." - + f"\nOnly run stubtest if you trust the {stub!r} package.", - "yellow", - ) + print( + colored( + f"\nSkipping stubtest for {stub!r}..." + + "\nNOTE: Running third-party stubtest involves downloading and executing arbitrary code from PyPI." + + f"\nOnly run stubtest if you trust the {stub!r} package.", + "yellow", ) + ) else: print(colored("\nSkipping stubtest since mypy failed.", "yellow"))