From 8c5c945014723dbb730abc11097a3408a4b8ac8b Mon Sep 17 00:00:00 2001 From: Paillat Date: Mon, 7 Jul 2025 20:59:07 +0200 Subject: [PATCH 1/6] :sparkles: Add `slotscheck` to ensure `__slots__` are used correctly --- .github/workflows/lib-checks.yml | 18 ++++++++++++++++++ .pre-commit-config.yaml | 8 ++++++++ discord/activity.py | 1 - discord/asset.py | 3 ++- discord/components.py | 1 - discord/emoji.py | 2 -- discord/partial_emoji.py | 2 +- discord/raw_models.py | 2 ++ discord/sticker.py | 4 ++-- discord/widget.py | 4 ---- pyproject.toml | 1 + uv.lock | 15 +++++++++++++++ 12 files changed, 49 insertions(+), 12 deletions(-) diff --git a/.github/workflows/lib-checks.yml b/.github/workflows/lib-checks.yml index 372b7fa281..25a713e933 100644 --- a/.github/workflows/lib-checks.yml +++ b/.github/workflows/lib-checks.yml @@ -93,3 +93,21 @@ jobs: run: mkdir -p -v .mypy_cache - name: "Run mypy" run: uv run mypy --non-interactive discord/ + slotscheck: + if: ${{ github.event_name != 'schedule' }} + runs-on: ubuntu-latest + steps: + - name: "Checkout Repository" + uses: actions/checkout@v4 + - name: "Setup Python" + uses: actions/setup-python@v5 + with: + python-version: "3.13" + - name: "Install uv" + uses: astral-sh/setup-uv@v6 + with: + enable-cache: true + - name: Sync dependencies + run: uv sync --no-python-downloads --group dev + - name: "Run slotscheck" + run: uv run slotscheck discord diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index e43197fe9e..94fb43bc89 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -33,3 +33,11 @@ repos: - id: prettier args: [--prose-wrap=always, --print-width=88] exclude: \.(po|pot|yml|yaml)$ + - repo: https://github.com/ariebovenberg/slotscheck + rev: v0.19.1 + hooks: + - id: slotscheck + additional_dependencies: + - "typing-extensions>=4,<5" + - "colorlog~=6.9.0" + - "aiohttp>=3.6.0,<4.0" \ No newline at end of file diff --git a/discord/activity.py b/discord/activity.py index 9cda6bc3f2..35e6f2c436 100644 --- a/discord/activity.py +++ b/discord/activity.py @@ -204,7 +204,6 @@ class Activity(BaseActivity): __slots__ = ( "state", "details", - "_created_at", "timestamps", "assets", "party", diff --git a/discord/asset.py b/discord/asset.py index 3bc04faa7c..b61e907c7a 100644 --- a/discord/asset.py +++ b/discord/asset.py @@ -51,6 +51,8 @@ class AssetMixin: url: str _state: Any | None + __slots__: tuple[str, ...] = ("_state", "url") + async def read(self) -> bytes: """|coro| @@ -148,7 +150,6 @@ class Asset(AssetMixin): """ __slots__: tuple[str, ...] = ( - "_state", "_url", "_animated", "_key", diff --git a/discord/components.py b/discord/components.py index 0d9a927a66..3c040a1857 100644 --- a/discord/components.py +++ b/discord/components.py @@ -154,7 +154,6 @@ class InputText(Component): """ __slots__: tuple[str, ...] = ( - "type", "style", "custom_id", "label", diff --git a/discord/emoji.py b/discord/emoji.py index 5dd1eafd3d..154166306c 100644 --- a/discord/emoji.py +++ b/discord/emoji.py @@ -53,9 +53,7 @@ class BaseEmoji(_EmojiTag, AssetMixin): "require_colons", "animated", "managed", - "id", "name", - "_state", "user", "available", ) diff --git a/discord/partial_emoji.py b/discord/partial_emoji.py index 9bf304bc75..decb3646f8 100644 --- a/discord/partial_emoji.py +++ b/discord/partial_emoji.py @@ -91,7 +91,7 @@ class PartialEmoji(_EmojiTag, AssetMixin): The ID of the custom emoji, if applicable. """ - __slots__ = ("animated", "name", "id", "_state") + __slots__ = ("animated", "name", "id") _CUSTOM_EMOJI_RE = re.compile(r"a)?:?(?P\w+):(?P[0-9]{13,20})>?") diff --git a/discord/raw_models.py b/discord/raw_models.py index e16a2f5018..ba44f92f37 100644 --- a/discord/raw_models.py +++ b/discord/raw_models.py @@ -85,6 +85,8 @@ class _RawReprMixin: + __slots__ = () + def __repr__(self) -> str: value = " ".join(f"{attr}={getattr(self, attr)!r}" for attr in self.__slots__) return f"<{self.__class__.__name__} {value}>" diff --git a/discord/sticker.py b/discord/sticker.py index 66d8d95ef9..cb985f5e9e 100644 --- a/discord/sticker.py +++ b/discord/sticker.py @@ -200,7 +200,7 @@ class StickerItem(_StickerTag): The URL for the sticker's image. """ - __slots__ = ("_state", "name", "id", "format", "url") + __slots__ = ("name", "id", "format") def __init__(self, *, state: ConnectionState, data: StickerItemPayload): self._state: ConnectionState = state @@ -271,7 +271,7 @@ class Sticker(_StickerTag): The URL for the sticker's image. """ - __slots__ = ("_state", "id", "name", "description", "format", "url") + __slots__ = ("id", "name", "description", "format") def __init__(self, *, state: ConnectionState, data: StickerPayload) -> None: self._state: ConnectionState = state diff --git a/discord/widget.py b/discord/widget.py index 004b87d66e..5b358352f3 100644 --- a/discord/widget.py +++ b/discord/widget.py @@ -152,13 +152,9 @@ class WidgetMember(BaseUser): """ __slots__ = ( - "name", "status", "nick", "avatar", - "discriminator", - "id", - "bot", "activity", "deafened", "suppress", diff --git a/pyproject.toml b/pyproject.toml index a18aebd5a8..3dacf970d3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -73,6 +73,7 @@ dev = [ "pytest~=8.3.5", "pytest-asyncio~=0.24.0", "ruff>=0.11.9", + "slotscheck>=0.19.1", ] [tool.hatch.version] diff --git a/uv.lock b/uv.lock index ddc382f09f..aae9400c37 100644 --- a/uv.lock +++ b/uv.lock @@ -1264,6 +1264,7 @@ dev = [ { name = "pytest" }, { name = "pytest-asyncio" }, { name = "ruff" }, + { name = "slotscheck" }, ] docs = [ { name = "furo" }, @@ -1299,6 +1300,7 @@ dev = [ { name = "pytest", specifier = "~=8.3.5" }, { name = "pytest-asyncio", specifier = "~=0.24.0" }, { name = "ruff", specifier = ">=0.11.9" }, + { name = "slotscheck", specifier = ">=0.19.1" }, ] docs = [ { name = "furo", specifier = "==2024.8.6" }, @@ -1613,6 +1615,19 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/a3/dc/17031897dae0efacfea57dfd3a82fdd2a2aeb58e0ff71b77b87e44edc772/setuptools-80.9.0-py3-none-any.whl", hash = "sha256:062d34222ad13e0cc312a4c02d73f059e86a4acbfbdea8f8f76b28c99f306922", size = 1201486 }, ] +[[package]] +name = "slotscheck" +version = "0.19.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "click" }, + { name = "tomli", marker = "python_full_version < '3.11'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/4b/57/6fcb8df11e7c76eb87b23bfa931408e47f051c6161749c531b4060a45516/slotscheck-0.19.1.tar.gz", hash = "sha256:6146b7747f8db335a00a66b782f86011b74b995f61746dc5b36a9e77d5326013", size = 16050 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/da/32/bd569256267f80b76b87d21a09795741a175778b954bee1d7b1a89852b6f/slotscheck-0.19.1-py3-none-any.whl", hash = "sha256:bff9926f8d6408ea21b6c6bbaa4389cea1682962e73ee4f30084b6d2b89260ee", size = 16995 }, +] + [[package]] name = "snowballstemmer" version = "3.0.1" From 03b78a76453fc484df11cd8531800f654db06b45 Mon Sep 17 00:00:00 2001 From: Lala Sabathil Date: Sun, 3 Aug 2025 14:09:01 +0200 Subject: [PATCH 2/6] fix(ci): re-run From a0cae22d6252572fdd9608d63d28988e02b39eed Mon Sep 17 00:00:00 2001 From: Paillat-dev Date: Wed, 3 Sep 2025 22:08:05 +0200 Subject: [PATCH 3/6] :bug: Fix overlapping slots in InputText --- discord/components.py | 1 - 1 file changed, 1 deletion(-) diff --git a/discord/components.py b/discord/components.py index fb014fdb0e..d9877f5205 100644 --- a/discord/components.py +++ b/discord/components.py @@ -226,7 +226,6 @@ class InputText(Component): "max_length", "required", "value", - "id", ) __repr_info__: ClassVar[tuple[str, ...]] = __slots__ From 24e4a35f718b442bd18afcf384fc42cd2c5b7e40 Mon Sep 17 00:00:00 2001 From: Paillat-dev Date: Wed, 3 Sep 2025 22:28:17 +0200 Subject: [PATCH 4/6] :wrench: Add language to slotscheck pre-commit config for renovate --- .pre-commit-config.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index db6d7d6b3c..402c534dbe 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -36,6 +36,7 @@ repos: rev: v0.19.1 hooks: - id: slotscheck + language: python additional_dependencies: - "typing-extensions>=4,<5" - "colorlog~=6.9.0" From 049517e858866187bb3cdbd79fff418fb3955ebb Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 3 Sep 2025 22:29:16 +0200 Subject: [PATCH 5/6] chore(deps): upgrade pre-commit hook astral-sh/ruff-pre-commit to v0.12.11 (#93) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 909a3d09ae..0eb5126370 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -10,7 +10,7 @@ repos: - id: end-of-file-fixer exclude: \.(po|pot|yml|yaml)$ - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.12.9 + rev: v0.12.11 hooks: - id: ruff args: [ --fix ] From 5241c3de380054053cfcfc62e0720672ec002634 Mon Sep 17 00:00:00 2001 From: Paillat-dev Date: Wed, 3 Sep 2025 22:41:02 +0200 Subject: [PATCH 6/6] :pushpin: Pin to specific version --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index ddf058ba22..a68967358b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -75,7 +75,7 @@ dev = [ "pytest-asyncio~=0.26.0", "python-dotenv>=1.1.1", "ruff>=0.11.9", - "slotscheck>=0.19.1", + "slotscheck==0.19.1", ] ci = [ "pygithub>=2.7.0",