Skip to content

Commit 25f3a4b

Browse files
authored
Merge branch 'Pycord-Development:master' into master
2 parents b46bfcf + 128a172 commit 25f3a4b

File tree

9 files changed

+55
-177
lines changed

9 files changed

+55
-177
lines changed

.github/workflows/todo-checks.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ jobs:
2323
- name: "Checkout Repository"
2424
uses: actions/checkout@v6
2525
- name: "Track TODO Action"
26-
uses: ribtoks/tdg-github-action@v0.4.15-beta
26+
uses: ribtoks/tdg-github-action@v0.4.16-beta
2727
with:
2828
TOKEN: ${{ secrets.GITHUB_TOKEN }}
2929
REPO: ${{ github.repository }}

CHANGELOG.md

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

1313
### Added
1414

15+
- Added `.extension` attribute to emojis to get their file extension.
16+
([#3055](https://github.com/Pycord-Development/pycord/pull/3055))
17+
1518
### Changed
1619

1720
- Updated `Role.is_assignable()` to also check whether the bot has the `MANAGE_ROLES`
@@ -21,11 +24,24 @@ These changes are available on the `master` branch, but have not yet been releas
2124

2225
- Fixed `RawMessageUpdateEvent.cached_message` being always `None` even when the message
2326
was cached. ([#3038](https://github.com/Pycord-Development/pycord/pull/3038))
27+
- Fixed downloading animated emojis which were originally uploaded as WebP files by
28+
changing the `.url` extension of animated emojis from .gif to .webp.
29+
([#3055](https://github.com/Pycord-Development/pycord/pull/3055))
30+
- Fixed `Interaction.channel` not being resolved with user-installed commands ran in
31+
guilds which the bot is not a member of.
32+
([#3047](https://github.com/Pycord-Development/pycord/pull/3047))
2433

2534
### Deprecated
2635

2736
### Removed
2837

38+
- Removed guild creation and ownership related methods and arguments as they're not
39+
allowed for bots anymore.
40+
([#3056](https://github.com/Pycord-Development/pycord/pull/3056))
41+
- Removed `Guild.set_mfa_required`, `Guild.delete`, `Template.create_guild` and
42+
`Client.create_guild`.
43+
- Removed the `owner` keyword argument from `Guild.edit`.
44+
2945
## [2.7.0] - 2025-12-24
3046

3147
### Added

discord/client.py

Lines changed: 0 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1708,55 +1708,6 @@ async def fetch_guild(self, guild_id: int, /, *, with_counts=True) -> Guild:
17081708
data = await self.http.get_guild(guild_id, with_counts=with_counts)
17091709
return Guild(data=data, state=self._connection)
17101710

1711-
async def create_guild(
1712-
self,
1713-
*,
1714-
name: str,
1715-
icon: bytes = MISSING,
1716-
code: str = MISSING,
1717-
) -> Guild:
1718-
"""|coro|
1719-
1720-
Creates a :class:`.Guild`.
1721-
1722-
Bot accounts in more than 10 guilds are not allowed to create guilds.
1723-
1724-
Parameters
1725-
----------
1726-
name: :class:`str`
1727-
The name of the guild.
1728-
icon: Optional[:class:`bytes`]
1729-
The :term:`py:bytes-like object` representing the icon. See :meth:`.ClientUser.edit`
1730-
for more details on what is expected.
1731-
code: :class:`str`
1732-
The code for a template to create the guild with.
1733-
1734-
.. versionadded:: 1.4
1735-
1736-
Returns
1737-
-------
1738-
:class:`.Guild`
1739-
The guild created. This is not the same guild that is
1740-
added to cache.
1741-
1742-
Raises
1743-
------
1744-
:exc:`HTTPException`
1745-
Guild creation failed.
1746-
:exc:`InvalidArgument`
1747-
Invalid icon image format given. Must be PNG or JPG.
1748-
"""
1749-
if icon is not MISSING:
1750-
icon_base64 = utils._bytes_to_base64_data(icon)
1751-
else:
1752-
icon_base64 = None
1753-
1754-
if code:
1755-
data = await self.http.create_from_template(code, name, icon_base64)
1756-
else:
1757-
data = await self.http.create_guild(name, icon_base64)
1758-
return Guild(data=data, state=self._connection)
1759-
17601711
async def fetch_stage_instance(self, channel_id: int, /) -> StageInstance:
17611712
"""|coro|
17621713

discord/emoji.py

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525

2626
from __future__ import annotations
2727

28-
from typing import TYPE_CHECKING, Any, Iterator
28+
from typing import TYPE_CHECKING, Any, Iterator, Literal
2929

3030
from .asset import Asset, AssetMixin
3131
from .partial_emoji import PartialEmoji, _EmojiTag
@@ -106,8 +106,10 @@ def created_at(self) -> datetime:
106106
@property
107107
def url(self) -> str:
108108
"""Returns the URL of the emoji."""
109-
fmt = "gif" if self.animated else "png"
110-
return f"{Asset.BASE}/emojis/{self.id}.{fmt}"
109+
url = f"{Asset.BASE}/emojis/{self.id}.{self.extension}"
110+
if self.animated:
111+
url += "?animated=true"
112+
return url
111113

112114
@property
113115
def mention(self) -> str:
@@ -116,6 +118,14 @@ def mention(self) -> str:
116118
return f"<a:{self.name}:{self.id}>"
117119
return f"<:{self.name}:{self.id}>"
118120

121+
@property
122+
def extension(self) -> Literal["webp", "png"]:
123+
"""Return the file extension of the emoji.
124+
125+
.. versionadded:: 2.7.1
126+
"""
127+
return "webp" if self.animated else "png"
128+
119129

120130
class GuildEmoji(BaseEmoji):
121131
"""Represents a custom emoji in a guild.

discord/guild.py

Lines changed: 1 addition & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -2082,43 +2082,6 @@ async def leave(self) -> None:
20822082
"""
20832083
await self._state.http.leave_guild(self.id)
20842084

2085-
async def delete(self) -> None:
2086-
"""|coro|
2087-
2088-
Deletes the guild. You must be the guild owner to delete the
2089-
guild.
2090-
2091-
Raises
2092-
------
2093-
HTTPException
2094-
Deleting the guild failed.
2095-
Forbidden
2096-
You do not have permissions to delete the guild.
2097-
"""
2098-
await self._state.http.delete_guild(self.id)
2099-
2100-
async def set_mfa_required(self, required: bool, *, reason: str = None) -> None:
2101-
"""|coro|
2102-
2103-
Set whether it is required to have MFA enabled on your account
2104-
to perform moderation actions. You must be the guild owner to do this.
2105-
2106-
Parameters
2107-
----------
2108-
required: :class:`bool`
2109-
Whether MFA should be required to perform moderation actions.
2110-
reason: :class:`str`
2111-
The reason to show up in the audit log.
2112-
2113-
Raises
2114-
------
2115-
HTTPException
2116-
The operation failed.
2117-
Forbidden
2118-
You are not the owner of the guild.
2119-
"""
2120-
await self._state.http.edit_guild_mfa(self.id, required, reason=reason)
2121-
21222085
async def edit(
21232086
self,
21242087
*,
@@ -2131,7 +2094,6 @@ async def edit(
21312094
discovery_splash: bytes | None = MISSING,
21322095
community: bool = MISSING,
21332096
afk_channel: VoiceChannel | None = MISSING,
2134-
owner: Snowflake = MISSING,
21352097
afk_timeout: int = MISSING,
21362098
default_notifications: NotificationLevel = MISSING,
21372099
verification_level: VerificationLevel = MISSING,
@@ -2195,9 +2157,6 @@ async def edit(
21952157
The new channel that is the AFK channel. Could be ``None`` for no AFK channel.
21962158
afk_timeout: :class:`int`
21972159
The number of seconds until someone is moved to the AFK channel.
2198-
owner: :class:`Member`
2199-
The new owner of the guild to transfer ownership to. Note that you must
2200-
be owner of the guild to do this.
22012160
verification_level: :class:`VerificationLevel`
22022161
The new verification level for the guild.
22032162
default_notifications: :class:`NotificationLevel`
@@ -2240,8 +2199,7 @@ async def edit(
22402199
Editing the guild failed.
22412200
InvalidArgument
22422201
The image format passed in to ``icon`` is invalid. It must be
2243-
PNG or JPG. This is also raised if you are not the owner of the
2244-
guild and request an ownership transfer.
2202+
PNG or JPG.
22452203
22462204
Returns
22472205
--------
@@ -2318,14 +2276,6 @@ async def edit(
23182276
else:
23192277
fields["public_updates_channel_id"] = public_updates_channel.id
23202278

2321-
if owner is not MISSING:
2322-
if self.owner_id != self._state.self_id:
2323-
raise InvalidArgument(
2324-
"To transfer ownership you must be the owner of the guild."
2325-
)
2326-
2327-
fields["owner_id"] = owner.id
2328-
23292279
if verification_level is not MISSING:
23302280
if not isinstance(verification_level, VerificationLevel):
23312281
raise InvalidArgument(

discord/http.py

Lines changed: 0 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1498,26 +1498,13 @@ def get_guild(
14981498
Route("GET", "/guilds/{guild_id}", guild_id=guild_id), params=params
14991499
)
15001500

1501-
def delete_guild(self, guild_id: Snowflake) -> Response[None]:
1502-
return self.request(Route("DELETE", "/guilds/{guild_id}", guild_id=guild_id))
1503-
1504-
def create_guild(self, name: str, icon: str | None) -> Response[guild.Guild]:
1505-
payload = {
1506-
"name": name,
1507-
}
1508-
if icon:
1509-
payload["icon"] = icon
1510-
1511-
return self.request(Route("POST", "/guilds"), json=payload)
1512-
15131501
def edit_guild(
15141502
self, guild_id: Snowflake, *, reason: str | None = None, **fields: Any
15151503
) -> Response[guild.Guild]:
15161504
valid_keys = (
15171505
"name",
15181506
"icon",
15191507
"afk_timeout",
1520-
"owner_id",
15211508
"afk_channel_id",
15221509
"splash",
15231510
"discovery_splash",
@@ -1543,15 +1530,6 @@ def edit_guild(
15431530
reason=reason,
15441531
)
15451532

1546-
def edit_guild_mfa(
1547-
self, guild_id: Snowflake, required: bool, *, reason: str | None
1548-
) -> Response[guild.GuildMFAModify]:
1549-
return self.request(
1550-
Route("POST", "/guilds/{guild_id}/mfa", guild_id=guild_id),
1551-
json={"level": int(required)},
1552-
reason=reason,
1553-
)
1554-
15551533
def get_template(self, code: str) -> Response[template.Template]:
15561534
return self.request(Route("GET", "/guilds/templates/{code}", code=code))
15571535

@@ -1608,19 +1586,6 @@ def delete_template(self, guild_id: Snowflake, code: str) -> Response[None]:
16081586
)
16091587
)
16101588

1611-
def create_from_template(
1612-
self, code: str, name: str, icon: str | None
1613-
) -> Response[guild.Guild]:
1614-
payload = {
1615-
"name": name,
1616-
}
1617-
if icon:
1618-
payload["icon"] = icon
1619-
1620-
return self.request(
1621-
Route("POST", "/guilds/templates/{code}", code=code), json=payload
1622-
)
1623-
16241589
def get_bans(
16251590
self,
16261591
guild_id: Snowflake,

discord/interactions.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,7 @@ def _from_data(self, data: InteractionPayload):
300300

301301
channel = data.get("channel")
302302
data_ch_type: int | None = channel.get("type") if channel else None
303+
factory: Any | None = None
303304

304305
if data_ch_type is not None:
305306
factory, ch_type = _threaded_channel_factory(data_ch_type)
@@ -308,6 +309,11 @@ def _from_data(self, data: InteractionPayload):
308309

309310
if self.channel is None and self.guild:
310311
self.channel = self.guild._resolve_channel(self.channel_id)
312+
if self.channel is None and factory is not None:
313+
self.channel = factory(
314+
state=self._state, data=channel, guild=self.guild
315+
)
316+
311317
if self.channel is None and self.channel_id is not None:
312318
ch_type = (
313319
ChannelType.text if self.guild_id is not None else ChannelType.private
@@ -932,7 +938,11 @@ async def _process_callback_response(
932938
"Channel for message could not be resolved. Please open a issue on GitHub if you encounter this error."
933939
)
934940
state = _InteractionMessageState(self._parent, self._parent._state)
935-
message = InteractionMessage(state=state, channel=channel, data=callback_response["resource"]["message"]) # type: ignore
941+
message = InteractionMessage(
942+
state=state,
943+
channel=channel,
944+
data=callback_response["resource"]["message"],
945+
) # type: ignore
936946
self._parent._original_response = message
937947

938948
self._parent.callback = InteractionCallback(callback_response["interaction"])

discord/partial_emoji.py

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
from __future__ import annotations
2727

2828
import re
29-
from typing import TYPE_CHECKING, Any, TypedDict, TypeVar
29+
from typing import TYPE_CHECKING, Any, Literal, TypedDict, TypeVar
3030

3131
from . import utils
3232
from .asset import Asset, AssetMixin
@@ -245,8 +245,18 @@ def url(self) -> str:
245245
if self.is_unicode_emoji():
246246
return ""
247247

248-
fmt = "gif" if self.animated else "png"
249-
return f"{Asset.BASE}/emojis/{self.id}.{fmt}"
248+
url = f"{Asset.BASE}/emojis/{self.id}.{self.extension}"
249+
if self.animated:
250+
url += "?animated=true"
251+
return url
252+
253+
@property
254+
def extension(self) -> Literal["webp", "png"]:
255+
"""Return the file extension of the emoji.
256+
257+
.. versionadded:: 2.7.1
258+
"""
259+
return "webp" if self.animated else "png"
250260

251261
async def read(self) -> bytes:
252262
if self.is_unicode_emoji():

discord/template.py

Lines changed: 0 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -168,40 +168,6 @@ def __repr__(self) -> str:
168168
f" creator={self.creator!r} source_guild={self.source_guild!r} is_dirty={self.is_dirty}>"
169169
)
170170

171-
async def create_guild(self, name: str, icon: Any = None) -> Guild:
172-
"""|coro|
173-
174-
Creates a :class:`.Guild` using the template.
175-
176-
Bot accounts in more than 10 guilds are not allowed to create guilds.
177-
178-
Parameters
179-
----------
180-
name: :class:`str`
181-
The name of the guild.
182-
icon: :class:`bytes`
183-
The :term:`py:bytes-like object` representing the icon. See :meth:`.ClientUser.edit`
184-
for more details on what is expected.
185-
186-
Returns
187-
-------
188-
:class:`.Guild`
189-
The guild created. This is not the same guild that is
190-
added to cache.
191-
192-
Raises
193-
------
194-
HTTPException
195-
Guild creation failed.
196-
InvalidArgument
197-
Invalid icon image format given. Must be PNG or JPG.
198-
"""
199-
if icon is not None:
200-
icon = _bytes_to_base64_data(icon)
201-
202-
data = await self._state.http.create_from_template(self.code, name, icon)
203-
return Guild(data=data, state=self._state)
204-
205171
async def sync(self) -> Template:
206172
"""|coro|
207173

0 commit comments

Comments
 (0)