diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index db6ec422f0..0c599e6c6d 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -56,6 +56,6 @@ repos: name: "run black in all files" - repo: https://github.com/charliermarsh/ruff-pre-commit - rev: v0.0.261 + rev: v0.0.292 hooks: - id: ruff diff --git a/disnake/enums.py b/disnake/enums.py index 29835a8715..b4bf3d994d 100644 --- a/disnake/enums.py +++ b/disnake/enums.py @@ -753,7 +753,7 @@ def __str__(self) -> str: # reference: https://discord.com/developers/docs/reference#locales class Locale(Enum): bg = "bg" - "Bulgarian | български" # noqa: RUF001 + "Bulgarian | български" cs = "cs" "Czech | Čeština" da = "da" @@ -761,7 +761,7 @@ class Locale(Enum): de = "de" "German | Deutsch" el = "el" - "Greek | Ελληνικά" # noqa: RUF001 + "Greek | Ελληνικά" en_GB = "en-GB" "English, UK | English, UK" en_US = "en-US" @@ -807,7 +807,7 @@ class Locale(Enum): tr = "tr" "Turkish | Türkçe" uk = "uk" - "Ukrainian | Українська" # noqa: RUF001 + "Ukrainian | Українська" vi = "vi" "Vietnamese | Tiếng Việt" zh_CN = "zh-CN" diff --git a/disnake/errors.py b/disnake/errors.py index 21a1834dff..416a32d7f1 100644 --- a/disnake/errors.py +++ b/disnake/errors.py @@ -2,7 +2,7 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Any, Dict, List, Optional, Tuple, Union +from typing import TYPE_CHECKING, Any, ClassVar, Dict, List, Mapping, Optional, Tuple, Union if TYPE_CHECKING: from aiohttp import ClientResponse, ClientWebSocketResponse @@ -225,7 +225,7 @@ class ConnectionClosed(ClientException): """ # https://discord.com/developers/docs/topics/opcodes-and-status-codes#gateway-gateway-close-event-codes - GATEWAY_CLOSE_EVENT_REASONS: Dict[int, str] = { + GATEWAY_CLOSE_EVENT_REASONS: ClassVar[Mapping[int, str]] = { 4000: "Unknown error", 4001: "Unknown opcode", 4002: "Decode error", @@ -243,7 +243,7 @@ class ConnectionClosed(ClientException): } # https://discord.com/developers/docs/topics/opcodes-and-status-codes#voice-voice-close-event-codes - GATEWAY_VOICE_CLOSE_EVENT_REASONS: Dict[int, str] = { + GATEWAY_VOICE_CLOSE_EVENT_REASONS: ClassVar[Mapping[int, str]] = { **GATEWAY_CLOSE_EVENT_REASONS, 4002: "Failed to decode payload", 4006: "Session no longer valid", diff --git a/disnake/ext/commands/context.py b/disnake/ext/commands/context.py index 5c25bdc9dc..0876e7d3a4 100644 --- a/disnake/ext/commands/context.py +++ b/disnake/ext/commands/context.py @@ -290,9 +290,7 @@ def voice_client(self) -> Optional[VoiceProtocol]: return g.voice_client if g else None async def send_help(self, *args: Any) -> Any: - """send_help(entity=) - - |coro| + """|coro| Shows the help command for the specified entity if given. The entity can be a command or a cog. diff --git a/disnake/ext/commands/help.py b/disnake/ext/commands/help.py index 54bcb1b43a..25a8c247dc 100644 --- a/disnake/ext/commands/help.py +++ b/disnake/ext/commands/help.py @@ -5,7 +5,7 @@ import functools import itertools import re -from typing import TYPE_CHECKING, Any, Callable, Iterable, Optional +from typing import TYPE_CHECKING, Any, Callable, ClassVar, Iterable, Mapping, Optional import disnake.utils @@ -279,7 +279,7 @@ class HelpCommand: ones passed in the :class:`.Command` constructor. """ - MENTION_TRANSFORMS = { + MENTION_TRANSFORMS: ClassVar[Mapping[str, str]] = { "@everyone": "@\u200beveryone", "@here": "@\u200bhere", r"<@!?[0-9]{17,19}>": "@deleted-user", diff --git a/disnake/opus.py b/disnake/opus.py index 596306dd6d..86a3ccbb70 100644 --- a/disnake/opus.py +++ b/disnake/opus.py @@ -234,12 +234,12 @@ def _load_default() -> bool: _bitness = struct.calcsize("P") * 8 _target = "x64" if _bitness > 32 else "x86" _filename = os.path.join(_basedir, "bin", f"libopus-0.{_target}.dll") - _lib = libopus_loader(_filename) # noqa: PLW0603 + _lib = libopus_loader(_filename) else: path = ctypes.util.find_library("opus") if not path: raise AssertionError("could not find the opus library") - _lib = libopus_loader(path) # noqa: PLW0603 + _lib = libopus_loader(path) except Exception: _lib = MISSING diff --git a/disnake/utils.py b/disnake/utils.py index 15b2f53ee0..95f35003ce 100644 --- a/disnake/utils.py +++ b/disnake/utils.py @@ -818,7 +818,7 @@ def replacement(match): regex = _MARKDOWN_STOCK_REGEX if ignore_links: regex = f"(?:{_URL_REGEX}|{regex})" - return re.sub(regex, replacement, text, 0, re.MULTILINE) + return re.sub(regex, replacement, text, flags=re.MULTILINE) def escape_markdown(text: str, *, as_needed: bool = False, ignore_links: bool = True) -> str: @@ -857,7 +857,7 @@ def replacement(match): regex = _MARKDOWN_STOCK_REGEX if ignore_links: regex = f"(?:{_URL_REGEX}|{regex})" - return re.sub(regex, replacement, text, 0, re.MULTILINE) + return re.sub(regex, replacement, text, flags=re.MULTILINE) else: text = re.sub(r"\\", r"\\\\", text) return _MARKDOWN_ESCAPE_REGEX.sub(r"\\\1", text) @@ -1134,8 +1134,10 @@ def evaluate_annotation( if implicit_str and isinstance(tp, str): if tp in cache: return cache[tp] - evaluated = eval( # noqa: PGH001 # this is how annotations are supposed to be unstringifed - tp, globals, locals + evaluated = ( + eval( # noqa: PGH001, S307 # this is how annotations are supposed to be unstringifed + tp, globals, locals + ) ) cache[tp] = evaluated return evaluate_annotation(evaluated, globals, locals, cache) diff --git a/docs/extensions/attributetable.py b/docs/extensions/attributetable.py index 1d6a2cb663..1a66a0c026 100644 --- a/docs/extensions/attributetable.py +++ b/docs/extensions/attributetable.py @@ -6,7 +6,7 @@ import inspect import re from collections import defaultdict -from typing import TYPE_CHECKING, DefaultDict, Dict, List, NamedTuple, Optional, Tuple +from typing import TYPE_CHECKING, ClassVar, DefaultDict, Dict, List, NamedTuple, Optional, Tuple from docutils import nodes from sphinx import addnodes @@ -17,6 +17,7 @@ from _types import SphinxExtensionMeta from sphinx.application import Sphinx from sphinx.environment import BuildEnvironment + from sphinx.util.typing import OptionSpec from sphinx.writers.html import HTMLTranslator @@ -100,7 +101,7 @@ class PyAttributeTable(SphinxDirective): required_arguments = 1 optional_arguments = 0 final_argument_whitespace = False - option_spec = {} + option_spec: ClassVar[OptionSpec] = {} def parse_name(self, content: str) -> Tuple[str, Optional[str]]: match = _name_parser_regex.match(content) diff --git a/pyproject.toml b/pyproject.toml index 369abf8c04..b5e09db246 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -72,7 +72,7 @@ tools = [ "python-dotenv~=1.0.0", "towncrier==23.6.0", "check-manifest==0.49", - "ruff==0.0.261", + "ruff==0.0.292", ] codemod = [ # run codemods on the respository (mostly automated typing) @@ -177,16 +177,24 @@ ignore = [ "RUF005", # might not be actually faster "RUF006", # might not be an issue/very extreme cases + # calling subprocess with dynamic arguments is generally fine, the only way to avoid this is ignoring it + "S603", + + # partial executable paths (i.e. "git" instead of "/usr/bin/git") are fine + "S607", + # ignore try-except-pass. Bare excepts are caught with E722 "S110", # provide specific codes on type: ignore "PGH003", + # typevar names don't match variance (we don't always want this) + "PLC0105", + # import aliases are fixed by isort "PLC0414", - # outer loop variables are overwritten by inner assignment target, these are mostly intentional "PLW2901", diff --git a/tests/test_utils.py b/tests/test_utils.py index 8c5ee4ec38..48ef75134a 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -377,7 +377,7 @@ class C(A): __slots__ = {"c": "uwu"} class D(B, C): - __slots__ = "xyz" + __slots__ = "xyz" # noqa: PLC0205 # this is intentional assert list(utils.get_slots(D)) == ["a", "a2", "c", "xyz"]