Skip to content

Commit 01e9fa8

Browse files
Lulalabyplun1331UnBonWhiskypre-commit-ci[bot]
authored andcommitted
fix: Patch TeamMember.permissions deserialization KeyError and use TeamMember.role instead
Co-Authored-By: plun1331 <plun1331@gmail.com> Co-Authored-By: ffouqueray <flavien.fouqueray@icloud.com> Co-Authored-By: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Lala Sabathil <lala@pycord.dev>
1 parent 94f03db commit 01e9fa8

File tree

6 files changed

+64
-9
lines changed

6 files changed

+64
-9
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@ These changes are available on the `master` branch, but have not yet been releas
1717

1818
### Changed
1919

20+
- `read_only` team members aren't considered as owners anymore when checking for app
21+
ownership permissions.
22+
2023
### Fixed
2124

2225
- Fixed internal use of deprecated role type methods.
@@ -29,6 +32,8 @@ These changes are available on the `master` branch, but have not yet been releas
2932
([#3189](https://github.com/Pycord-Development/pycord/pull/3189))
3033
- Fixed incorrect type hints for `MessagePinIterator`.
3134
([#3178](https://github.com/Pycord-Development/pycord/pull/3178))
35+
- Fixed a `KeyError` when fetching an app's information or checking for app ownership
36+
with `is_owner`.
3237

3338
### Deprecated
3439

discord/bot.py

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@
5757
UserCommand,
5858
command,
5959
)
60-
from .enums import IntegrationType, InteractionContextType, InteractionType
60+
from .enums import IntegrationType, InteractionContextType, InteractionType, TeamRole
6161
from .errors import CheckFailure, DiscordException
6262
from .interactions import Interaction
6363
from .shard import AutoShardedClient
@@ -1441,7 +1441,8 @@ async def is_owner(self, user: User | Member) -> bool:
14411441
this bot.
14421442
14431443
If an :attr:`owner_id` is not set, it is fetched automatically
1444-
through the use of :meth:`~.Bot.application_info`.
1444+
through the use of :meth:`~.Bot.application_info`, returning
1445+
the application owner, or all non read-only team members.
14451446
14461447
.. versionchanged:: 1.3
14471448
The function also checks if the application is team-owned if
@@ -1465,7 +1466,9 @@ async def is_owner(self, user: User | Member) -> bool:
14651466
else:
14661467
app = await self.application_info() # type: ignore
14671468
if app.team:
1468-
self.owner_ids = ids = {m.id for m in app.team.members}
1469+
self.owner_ids = ids = {
1470+
m.id for m in app.team.members if m.role is not TeamRole.read_only
1471+
}
14691472
return user.id in ids
14701473
else:
14711474
self.owner_id = owner_id = app.owner.id
@@ -1491,11 +1494,12 @@ class Bot(BotBase, Client):
14911494
owner_id: Optional[:class:`int`]
14921495
The user ID that owns the bot. If this is not set and is then queried via
14931496
:meth:`.is_owner` then it is fetched automatically using
1494-
:meth:`~.Bot.application_info`.
1497+
:meth:`~.Bot.application_info`, returning the application owner.
14951498
owner_ids: Optional[Collection[:class:`int`]]
14961499
The user IDs that owns the bot. This is similar to :attr:`owner_id`.
14971500
If this is not set and the application is team based, then it is
1498-
fetched automatically using :meth:`~.Bot.application_info`.
1501+
fetched automatically using :meth:`~.Bot.application_info`,
1502+
returning all non read-only team members.
14991503
For performance reasons it is recommended to use a :class:`set`
15001504
for the collection. You cannot set both ``owner_id`` and ``owner_ids``.
15011505

discord/enums.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
"ActivityType",
4646
"NotificationLevel",
4747
"TeamMembershipState",
48+
"TeamRole",
4849
"WebhookType",
4950
"ExpireBehaviour",
5051
"ExpireBehavior",
@@ -629,6 +630,15 @@ class TeamMembershipState(Enum):
629630
accepted = 2
630631

631632

633+
class TeamRole(Enum):
634+
"""Role of a team member."""
635+
636+
owner = "owner"
637+
admin = "admin"
638+
developer = "developer"
639+
read_only = "read_only"
640+
641+
632642
class WebhookType(Enum):
633643
"""Webhook Type"""
634644

discord/team.py

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,11 @@
2727

2828
from typing import TYPE_CHECKING
2929

30+
from typing_extensions import deprecated
31+
3032
from . import utils
3133
from .asset import Asset
32-
from .enums import TeamMembershipState, try_enum
34+
from .enums import TeamMembershipState, TeamRole, try_enum
3335
from .user import BaseUser
3436

3537
if TYPE_CHECKING:
@@ -136,16 +138,22 @@ class TeamMember(BaseUser):
136138
The team that the member is from.
137139
membership_state: :class:`TeamMembershipState`
138140
The membership state of the member (e.g. invited or accepted)
141+
role: :class:`TeamRole`
142+
The role of the team member (e.g. admin, developer, read_only).
139143
"""
140144

141-
__slots__ = ("team", "membership_state", "permissions")
145+
__slots__ = ("team", "membership_state", "role")
142146

143147
def __init__(self, team: Team, state: ConnectionState, data: TeamMemberPayload):
144148
self.team: Team = team
145149
self.membership_state: TeamMembershipState = try_enum(
146150
TeamMembershipState, data["membership_state"]
147151
)
148-
self.permissions: list[str] = data["permissions"]
152+
self.role: TeamRole = (
153+
TeamRole.owner
154+
if team.owner_id == int(data["user"]["id"])
155+
else try_enum(TeamRole, data["role"])
156+
)
149157
super().__init__(state=state, data=data["user"])
150158

151159
def __repr__(self) -> str:
@@ -163,3 +171,10 @@ def __repr__(self) -> str:
163171
f"<{self.__class__.__name__} id={self.id} name={self.name!r} "
164172
f"discriminator={self.discriminator!r} membership_state={self.membership_state!r}>"
165173
)
174+
175+
@property
176+
@deprecated(
177+
"TeamMember.permissions is deprecated and will return an empty list. Use TeamMember.role instead."
178+
)
179+
def permissions(self) -> list[str]:
180+
return []

discord/types/team.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
class TeamMember(TypedDict):
3535
user: PartialUser
3636
membership_state: int
37-
permissions: list[str]
37+
role: str
3838
team_id: Snowflake
3939

4040

docs/api/enums.rst

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2681,3 +2681,24 @@ of :class:`enum.Enum`.
26812681

26822682
.. attribute:: disabled_by_discord
26832683
The application webhook is disabled by Discord.
2684+
2685+
.. class:: TeamRole
2686+
Represents a app team role.
2687+
2688+
.. versionadded:: 2.8
2689+
2690+
.. attribute:: owner
2691+
2692+
Represents the team owner role.
2693+
2694+
.. attribute:: admin
2695+
2696+
Represents the team admin role.
2697+
2698+
.. attribute:: developer
2699+
2700+
Represents the team developer role.
2701+
2702+
.. attribute:: read_only
2703+
2704+
Represents the team read only role.

0 commit comments

Comments
 (0)