From cc2f3464e19dc1d679674cd5cc22b76eaac35f5b Mon Sep 17 00:00:00 2001 From: shiftinv Date: Fri, 16 Jun 2023 12:38:27 +0200 Subject: [PATCH 1/6] typing: make `abc.User.avatar` a property to match implementations --- disnake/abc.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/disnake/abc.py b/disnake/abc.py index 980a0ccb06..45fdbcad25 100644 --- a/disnake/abc.py +++ b/disnake/abc.py @@ -146,8 +146,6 @@ class User(Snowflake, Protocol): .. versionadded:: 2.9 - avatar: :class:`~disnake.Asset` - The avatar asset the user has. bot: :class:`bool` Whether the user is a bot account. """ @@ -157,7 +155,6 @@ class User(Snowflake, Protocol): name: str discriminator: str global_name: Optional[str] - avatar: Asset bot: bool @property @@ -170,6 +167,13 @@ def mention(self) -> str: """:class:`str`: Returns a string that allows you to mention the given user.""" raise NotImplementedError + @property + def avatar(self) -> Optional[Asset]: + """Optional[:class:`~disnake.Asset`]: Returns an :class:`~disnake.Asset` for + the avatar the user has. + """ + raise NotImplementedError + @runtime_checkable class PrivateChannel(Snowflake, Protocol): From a3d46e4f7a73d1201ec5262e57d6b517acbd6429 Mon Sep 17 00:00:00 2001 From: shiftinv Date: Fri, 16 Jun 2023 12:46:19 +0200 Subject: [PATCH 2/6] fix: remove unnecessary `Member.discriminator` passthrough --- disnake/member.py | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/disnake/member.py b/disnake/member.py index daf8fa7cbf..f3ff9008f7 100644 --- a/disnake/member.py +++ b/disnake/member.py @@ -279,6 +279,7 @@ class Member(disnake.abc.Messageable, _UserTag): if TYPE_CHECKING: name: str id: int + discriminator: str global_name: Optional[str] bot: bool system: bool @@ -487,19 +488,7 @@ def status(self, value: Status) -> None: @property def tag(self) -> str: """:class:`str`: An alias of :attr:`.discriminator`.""" - return self._user.discriminator - - @property - def discriminator(self) -> str: - """:class:`str`: The user's discriminator. - - .. note:: - This is being phased out by Discord; the username system is moving away from ``username#discriminator`` - to users having a globally unique username. - The value of a single zero (``"0"``) indicates that the user has been migrated to the new system. - See the `help article `__ for details. - """ - return self._user.discriminator + return self.discriminator @property def mobile_status(self) -> Status: From c078fe8a2ac111a717ce834f461399a4f4b04194 Mon Sep 17 00:00:00 2001 From: shiftinv Date: Fri, 16 Jun 2023 12:47:46 +0200 Subject: [PATCH 3/6] test: add protocol assignability typing test --- tests/test_abc.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/tests/test_abc.py b/tests/test_abc.py index 196b71c38b..8fbfd1d29b 100644 --- a/tests/test_abc.py +++ b/tests/test_abc.py @@ -1,5 +1,6 @@ # SPDX-License-Identifier: MIT +from typing import cast from unittest import mock import pytest @@ -151,3 +152,16 @@ async def test_overwrites(self, channel, sync_permissions) -> None: channel._state.http.edit_channel.assert_awaited_once_with( channel.id, permission_overwrites=[], reason=None ) + + +class TestUserProtocol: + def handle_abc_user(self, user: disnake.abc.User) -> None: + ... + + def _test_typing_assignable(self): + # All of these should match the abc.User protocol and thus type-check correctly + # (they could just inherit from the protocol to ensure correct implementation, + # but we really only want structural (i.e. implicit) subtyping) + self.handle_abc_user(cast(disnake.User, ...)) + self.handle_abc_user(cast(disnake.ClientUser, ...)) + self.handle_abc_user(cast(disnake.Member, ...)) From f74fe291321ae7afd3ecc73ba3b963ec3abd8f74 Mon Sep 17 00:00:00 2001 From: shiftinv Date: Fri, 16 Jun 2023 13:00:53 +0200 Subject: [PATCH 4/6] docs: add changelog entry --- changelog/1051.bugfix.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog/1051.bugfix.rst diff --git a/changelog/1051.bugfix.rst b/changelog/1051.bugfix.rst new file mode 100644 index 0000000000..de4cb4ac01 --- /dev/null +++ b/changelog/1051.bugfix.rst @@ -0,0 +1 @@ +Fix typing issue with :class:`abc.User` protocol requirements, which previously resulted in :class:`User` and :class:`Member` not conforming to the protocol. From cfe16f2354cc5deff147c2eef5011d2ba9cc056e Mon Sep 17 00:00:00 2001 From: shiftinv Date: Fri, 16 Jun 2023 13:26:06 +0200 Subject: [PATCH 5/6] chore: fix autotyping --- tests/test_abc.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_abc.py b/tests/test_abc.py index 8fbfd1d29b..34464a5aba 100644 --- a/tests/test_abc.py +++ b/tests/test_abc.py @@ -158,7 +158,7 @@ class TestUserProtocol: def handle_abc_user(self, user: disnake.abc.User) -> None: ... - def _test_typing_assignable(self): + def _test_typing_assignable(self) -> None: # All of these should match the abc.User protocol and thus type-check correctly # (they could just inherit from the protocol to ensure correct implementation, # but we really only want structural (i.e. implicit) subtyping) From 47553e3fcfda5f3e188d21e9f8e3eaca27c5ae75 Mon Sep 17 00:00:00 2001 From: shiftinv Date: Mon, 19 Jun 2023 13:59:13 +0200 Subject: [PATCH 6/6] chore: move test method --- tests/test_abc.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/test_abc.py b/tests/test_abc.py index 34464a5aba..844904630b 100644 --- a/tests/test_abc.py +++ b/tests/test_abc.py @@ -155,13 +155,13 @@ async def test_overwrites(self, channel, sync_permissions) -> None: class TestUserProtocol: - def handle_abc_user(self, user: disnake.abc.User) -> None: - ... - def _test_typing_assignable(self) -> None: + def handle_abc_user(user: disnake.abc.User) -> None: + ... + # All of these should match the abc.User protocol and thus type-check correctly # (they could just inherit from the protocol to ensure correct implementation, # but we really only want structural (i.e. implicit) subtyping) - self.handle_abc_user(cast(disnake.User, ...)) - self.handle_abc_user(cast(disnake.ClientUser, ...)) - self.handle_abc_user(cast(disnake.Member, ...)) + handle_abc_user(cast(disnake.User, ...)) + handle_abc_user(cast(disnake.ClientUser, ...)) + handle_abc_user(cast(disnake.Member, ...))