diff --git a/.github/workflows/lib-checks.yml b/.github/workflows/lib-checks.yml index d3d89ad742..c2f10142eb 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 0eb5126370..18f6a4d555 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -32,3 +32,12 @@ 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 + language: python + 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 3377892aa8..a71abd8649 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 c54162de83..266fa16a29 100644 --- a/discord/asset.py +++ b/discord/asset.py @@ -56,6 +56,8 @@ class AssetMixin: url: str _state: Any | None + __slots__: tuple[str, ...] = ("_state", "url") + async def read(self) -> bytes: """|coro| @@ -155,7 +157,6 @@ class Asset(AssetMixin): """ __slots__: tuple[str, ...] = ( - "_state", "_url", "_animated", "_key", diff --git a/discord/components.py b/discord/components.py index 4cd8c0e1c0..1e5a18db40 100644 --- a/discord/components.py +++ b/discord/components.py @@ -219,7 +219,6 @@ class InputText(Component): """ __slots__: tuple[str, ...] = ( - "type", "style", "custom_id", "label", @@ -228,7 +227,6 @@ class InputText(Component): "max_length", "required", "value", - "id", ) __repr_info__: ClassVar[tuple[str, ...]] = __slots__ diff --git a/discord/emoji.py b/discord/emoji.py index 40df9ca252..85bb051ffe 100644 --- a/discord/emoji.py +++ b/discord/emoji.py @@ -54,9 +54,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 b59e1e9fdd..39bbf506d6 100644 --- a/discord/partial_emoji.py +++ b/discord/partial_emoji.py @@ -92,7 +92,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 6fb3e5ba38..8f48226c31 100644 --- a/discord/sticker.py +++ b/discord/sticker.py @@ -201,7 +201,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 @@ -272,7 +272,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 eb54e606b3..d4cb03acf4 100644 --- a/discord/widget.py +++ b/discord/widget.py @@ -153,13 +153,9 @@ class WidgetMember(BaseUser): """ __slots__ = ( - "name", "status", "nick", "avatar", - "discriminator", - "id", - "bot", "activity", "deafened", "suppress", diff --git a/pyproject.toml b/pyproject.toml index 6473d4cdc8..bcb3b518f6 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -75,6 +75,7 @@ dev = [ "pytest-asyncio~=0.26.0", "python-dotenv>=1.1.1", "ruff>=0.11.9", + "slotscheck==0.19.1", ] ci = [ "pygithub>=2.7.0", diff --git a/uv.lock b/uv.lock index bcbffc0b57..028309d965 100644 --- a/uv.lock +++ b/uv.lock @@ -1360,6 +1360,7 @@ dev = [ { name = "pytest-asyncio" }, { name = "python-dotenv" }, { name = "ruff" }, + { name = "slotscheck" }, ] docs = [ { name = "furo" }, @@ -1397,6 +1398,7 @@ dev = [ { name = "pytest-asyncio", specifier = "~=0.26.0" }, { name = "python-dotenv", specifier = ">=1.1.1" }, { name = "ruff", specifier = ">=0.11.9" }, + { name = "slotscheck", specifier = ">=0.19.1" }, ] docs = [ { name = "furo", specifier = "==2024.8.6" }, @@ -1766,6 +1768,19 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/84/a8/001d4a7c2b37623a3fd7463208267fb906df40ff31db496157549cfd6e72/ruff-0.12.11-py3-none-win_arm64.whl", hash = "sha256:bae4d6e6a2676f8fb0f98b74594a048bae1b944aab17e9f5d504062303c6dbea", size = 12135290, upload-time = "2025-08-28T13:59:06.933Z" }, ] +[[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"