From ea6caccc60066c8d38dddb94bfcd87bef7bc2cb0 Mon Sep 17 00:00:00 2001 From: SilberGecko6917 Date: Thu, 2 Jul 2026 15:07:25 +0200 Subject: [PATCH 1/8] replace gif with webp --- discord/asset.py | 65 +++++++++++++++++++++--------------------------- 1 file changed, 28 insertions(+), 37 deletions(-) diff --git a/discord/asset.py b/discord/asset.py index 659d6dd5eb..817828fa8a 100644 --- a/discord/asset.py +++ b/discord/asset.py @@ -178,13 +178,11 @@ def _from_default_avatar(cls, state, index: int) -> Asset: @classmethod def _from_avatar(cls, state, user_id: int, avatar: str) -> Asset: animated = avatar.startswith("a_") - format = "gif" if animated else "png" - return cls( - state, - url=f"{cls.BASE}/avatars/{user_id}/{avatar}.{format}?size=1024", - key=avatar, - animated=animated, - ) + if animated: + url = f"{cls.BASE}/avatars/{user_id}/{avatar}.webp?animated=true&size=1024" + else: + url = f"{cls.BASE}/avatars/{user_id}/{avatar}.png?size=1024" + return cls(state, url=url, key=avatar, animated=animated) @classmethod def _from_avatar_decoration( @@ -235,26 +233,22 @@ def _from_guild_avatar( cls, state, guild_id: int, member_id: int, avatar: str ) -> Asset: animated = avatar.startswith("a_") - format = "gif" if animated else "png" - return cls( - state, - url=f"{cls.BASE}/guilds/{guild_id}/users/{member_id}/avatars/{avatar}.{format}?size=1024", - key=avatar, - animated=animated, - ) + if animated: + url = f"{cls.BASE}/guilds/{guild_id}/users/{member_id}/avatars/{avatar}.webp?animated=true&size=1024" + else: + url = f"{cls.BASE}/guilds/{guild_id}/users/{member_id}/avatars/{avatar}.png?size=1024" + return cls(state, url=url, key=avatar, animated=animated) @classmethod def _from_guild_banner( cls, state, guild_id: int, member_id: int, banner: str ) -> Asset: animated = banner.startswith("a_") - format = "gif" if animated else "png" - return cls( - state, - url=f"{cls.BASE}/guilds/{guild_id}/users/{member_id}/banners/{banner}.{format}?size=512", - key=banner, - animated=animated, - ) + if animated: + url = f"{cls.BASE}/guilds/{guild_id}/users/{member_id}/banners/{banner}.webp?animated=true&size=512" + else: + url = f"{cls.BASE}/guilds/{guild_id}/users/{member_id}/banners/{banner}.png?size=512" + return cls(state, url=url, key=banner, animated=animated) @classmethod def _from_icon(cls, state, object_id: int, icon_hash: str, path: str) -> Asset: @@ -292,11 +286,12 @@ def _from_guild_image(cls, state, guild_id: int, image: str, path: str) -> Asset format = "png" if path == "banners": animated = image.startswith("a_") - format = "gif" if animated else "png" + format = "webp" if animated else "png" + extra = "&animated=true" if animated else "" return cls( state, - url=f"{cls.BASE}/{path}/{guild_id}/{image}.{format}?size=1024", + url=f"{cls.BASE}/{path}/{guild_id}/{image}.{format}?size=1024{extra}", key=image, animated=animated, ) @@ -304,13 +299,11 @@ def _from_guild_image(cls, state, guild_id: int, image: str, path: str) -> Asset @classmethod def _from_guild_icon(cls, state, guild_id: int, icon_hash: str) -> Asset: animated = icon_hash.startswith("a_") - format = "gif" if animated else "png" - return cls( - state, - url=f"{cls.BASE}/icons/{guild_id}/{icon_hash}.{format}?size=1024", - key=icon_hash, - animated=animated, - ) + if animated: + url = f"{cls.BASE}/icons/{guild_id}/{icon_hash}.webp?animated=true&size=1024" + else: + url = f"{cls.BASE}/icons/{guild_id}/{icon_hash}.png?size=1024" + return cls(state, url=url, key=icon_hash, animated=animated) @classmethod def _from_sticker_banner(cls, state, banner: int) -> Asset: @@ -324,13 +317,11 @@ def _from_sticker_banner(cls, state, banner: int) -> Asset: @classmethod def _from_user_banner(cls, state, user_id: int, banner_hash: str) -> Asset: animated = banner_hash.startswith("a_") - format = "gif" if animated else "png" - return cls( - state, - url=f"{cls.BASE}/banners/{user_id}/{banner_hash}.{format}?size=512", - key=banner_hash, - animated=animated, - ) + if animated: + url = f"{cls.BASE}/banners/{user_id}/{banner_hash}.webp?animated=true&size=512" + else: + url = f"{cls.BASE}/banners/{user_id}/{banner_hash}.png?size=512" + return cls(state, url=url, key=banner_hash, animated=animated) @classmethod def _from_scheduled_event_image( From 7c3e47e9a6c39c2c8aae76ecd314369fff62c406 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Thu, 2 Jul 2026 13:27:29 +0000 Subject: [PATCH 2/8] style(pre-commit): auto fixes from pre-commit.com hooks --- discord/asset.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/discord/asset.py b/discord/asset.py index 817828fa8a..1983c90916 100644 --- a/discord/asset.py +++ b/discord/asset.py @@ -300,7 +300,9 @@ def _from_guild_image(cls, state, guild_id: int, image: str, path: str) -> Asset def _from_guild_icon(cls, state, guild_id: int, icon_hash: str) -> Asset: animated = icon_hash.startswith("a_") if animated: - url = f"{cls.BASE}/icons/{guild_id}/{icon_hash}.webp?animated=true&size=1024" + url = ( + f"{cls.BASE}/icons/{guild_id}/{icon_hash}.webp?animated=true&size=1024" + ) else: url = f"{cls.BASE}/icons/{guild_id}/{icon_hash}.png?size=1024" return cls(state, url=url, key=icon_hash, animated=animated) From 8b3fcc62721799db8df47dd4692bc375d43b6759 Mon Sep 17 00:00:00 2001 From: SilberGecko6917 Date: Thu, 2 Jul 2026 15:29:33 +0200 Subject: [PATCH 3/8] add changelog --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7647529eee..331a9618dc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,8 @@ These changes are available on the `master` branch, but have not yet been releas ### Fixed +- Fix animated asset url extension from `.gif` to `.webp` + ([#3294](https://github.com/Pycord-Development/pycord/pull/3294)) - Fix an attribute error in `RoleColours.is_holographic()` when `secondary` or `tertiary` is `None`. ([#3268](https://github.com/Pycord-Development/pycord/pull/3268)) From 67b021037f23a438592138b085c301d28d536908 Mon Sep 17 00:00:00 2001 From: SilberGecko6917 Date: Sat, 4 Jul 2026 20:26:06 +0200 Subject: [PATCH 4/8] add new properties and change some things --- CHANGELOG.md | 2 ++ discord/asset.py | 56 +++++++++++++++++++++++++++--------------------- 2 files changed, 34 insertions(+), 24 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 331a9618dc..f063feb315 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,8 @@ These changes are available on the `master` branch, but have not yet been releas - Add `RoleColours.HOLOGRAPHIC_PRIMARY`, `RoleColours.HOLOGRAPHIC_SECONDARY`, and `RoleColours.HOLOGRAPHIC_TERTIARY` class constants. ([#3268](https://github.com/Pycord-Development/pycord/pull/3268)) +- Add `Asset.size`, `Asset.extention` properties. + ([#3294](https://github.com/Pycord-Development/pycord/pull/3294)) ### Changed diff --git a/discord/asset.py b/discord/asset.py index 1983c90916..987b8aa041 100644 --- a/discord/asset.py +++ b/discord/asset.py @@ -178,10 +178,10 @@ def _from_default_avatar(cls, state, index: int) -> Asset: @classmethod def _from_avatar(cls, state, user_id: int, avatar: str) -> Asset: animated = avatar.startswith("a_") + format = "webp" if animated else "png" + url = f"{cls.BASE}/avatars/{user_id}/{avatar}.{format}?size=1024" if animated: - url = f"{cls.BASE}/avatars/{user_id}/{avatar}.webp?animated=true&size=1024" - else: - url = f"{cls.BASE}/avatars/{user_id}/{avatar}.png?size=1024" + url += "&animated=true" return cls(state, url=url, key=avatar, animated=animated) @classmethod @@ -233,10 +233,10 @@ def _from_guild_avatar( cls, state, guild_id: int, member_id: int, avatar: str ) -> Asset: animated = avatar.startswith("a_") + format = "webp" if animated else "png" + url = f"{cls.BASE}/guilds/{guild_id}/users/{member_id}/avatars/{avatar}.{format}?size=1024" if animated: - url = f"{cls.BASE}/guilds/{guild_id}/users/{member_id}/avatars/{avatar}.webp?animated=true&size=1024" - else: - url = f"{cls.BASE}/guilds/{guild_id}/users/{member_id}/avatars/{avatar}.png?size=1024" + url += "&animated=true" return cls(state, url=url, key=avatar, animated=animated) @classmethod @@ -244,10 +244,10 @@ def _from_guild_banner( cls, state, guild_id: int, member_id: int, banner: str ) -> Asset: animated = banner.startswith("a_") + format = "webp" if animated else "png" + url = f"{cls.BASE}/guilds/{guild_id}/users/{member_id}/banners/{banner}.{format}?size=512" if animated: - url = f"{cls.BASE}/guilds/{guild_id}/users/{member_id}/banners/{banner}.webp?animated=true&size=512" - else: - url = f"{cls.BASE}/guilds/{guild_id}/users/{member_id}/banners/{banner}.png?size=512" + url += "&animated=true" return cls(state, url=url, key=banner, animated=animated) @classmethod @@ -288,23 +288,18 @@ def _from_guild_image(cls, state, guild_id: int, image: str, path: str) -> Asset animated = image.startswith("a_") format = "webp" if animated else "png" - extra = "&animated=true" if animated else "" - return cls( - state, - url=f"{cls.BASE}/{path}/{guild_id}/{image}.{format}?size=1024{extra}", - key=image, - animated=animated, - ) + url = f"{cls.BASE}/{path}/{guild_id}/{image}.{format}?size=1024" + if animated: + url += "&animated=true" + return cls(state, url=url, key=image, animated=animated) @classmethod def _from_guild_icon(cls, state, guild_id: int, icon_hash: str) -> Asset: animated = icon_hash.startswith("a_") + format = "webp" if animated else "png" + url = f"{cls.BASE}/icons/{guild_id}/{icon_hash}.{format}?size=1024" if animated: - url = ( - f"{cls.BASE}/icons/{guild_id}/{icon_hash}.webp?animated=true&size=1024" - ) - else: - url = f"{cls.BASE}/icons/{guild_id}/{icon_hash}.png?size=1024" + url += "&animated=true" return cls(state, url=url, key=icon_hash, animated=animated) @classmethod @@ -319,10 +314,10 @@ def _from_sticker_banner(cls, state, banner: int) -> Asset: @classmethod def _from_user_banner(cls, state, user_id: int, banner_hash: str) -> Asset: animated = banner_hash.startswith("a_") + format = "webp" if animated else "png" + url = f"{cls.BASE}/banners/{user_id}/{banner_hash}.{format}?size=512" if animated: - url = f"{cls.BASE}/banners/{user_id}/{banner_hash}.webp?animated=true&size=512" - else: - url = f"{cls.BASE}/banners/{user_id}/{banner_hash}.png?size=512" + url += "&animated=true" return cls(state, url=url, key=banner_hash, animated=animated) @classmethod @@ -370,6 +365,19 @@ def key(self) -> str: """Returns the identifying key of the asset.""" return self._key + @property + def extension(self) -> Literal["webp", "png"]: + """Returns the extension of the asset.""" + return "webp" if self._animated else "png" + + @property + def size(self) -> int | None: + """Returns the size of the asset.""" + + query = yarl.URL(self._url).query + size = query.get("size") + return int(size) if size is not None else None + def is_animated(self) -> bool: """Returns whether the asset is animated.""" return self._animated From 9741d789053fc8ad42891d6a5ef064be271a656d Mon Sep 17 00:00:00 2001 From: SilberGecko6917 Date: Sun, 5 Jul 2026 01:00:08 +0200 Subject: [PATCH 5/8] get size and extension in init --- discord/asset.py | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/discord/asset.py b/discord/asset.py index 987b8aa041..da37589b00 100644 --- a/discord/asset.py +++ b/discord/asset.py @@ -156,6 +156,8 @@ class Asset(AssetMixin): "_url", "_animated", "_key", + "_extension", + "_size", ) BASE = "https://cdn.discordapp.com" @@ -166,6 +168,13 @@ def __init__(self, state, *, url: str, key: str, animated: bool = False): self._animated = animated self._key = key + parsed = yarl.URL(url) + _, ext = os.path.splitext(parsed.path) + self._extension = ext.lstrip(".") + + size = parsed.query.get("size") + self._size = int(size) if size is not None else None + @classmethod def _from_default_avatar(cls, state, index: int) -> Asset: return cls( @@ -366,17 +375,14 @@ def key(self) -> str: return self._key @property - def extension(self) -> Literal["webp", "png"]: + def extension(self) -> str: """Returns the extension of the asset.""" - return "webp" if self._animated else "png" + return self._extension @property def size(self) -> int | None: """Returns the size of the asset.""" - - query = yarl.URL(self._url).query - size = query.get("size") - return int(size) if size is not None else None + return self._size def is_animated(self) -> bool: """Returns whether the asset is animated.""" From 2f09700bcff08620913e3771ad17a8190ca8996c Mon Sep 17 00:00:00 2001 From: SilberGecko6917 Date: Sun, 5 Jul 2026 14:59:47 +0200 Subject: [PATCH 6/8] requested changes --- discord/asset.py | 106 ++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 86 insertions(+), 20 deletions(-) diff --git a/discord/asset.py b/discord/asset.py index da37589b00..3519fa9ec2 100644 --- a/discord/asset.py +++ b/discord/asset.py @@ -162,18 +162,22 @@ class Asset(AssetMixin): BASE = "https://cdn.discordapp.com" - def __init__(self, state, *, url: str, key: str, animated: bool = False): + def __init__( + self, + state, + *, + url: str, + key: str, + animated: bool = False, + extension: str | None = None, + size: int | None = None, + ): self._state = state self._url = url self._animated = animated self._key = key - - parsed = yarl.URL(url) - _, ext = os.path.splitext(parsed.path) - self._extension = ext.lstrip(".") - - size = parsed.query.get("size") - self._size = int(size) if size is not None else None + self._extension = extension + self._size = size @classmethod def _from_default_avatar(cls, state, index: int) -> Asset: @@ -182,6 +186,7 @@ def _from_default_avatar(cls, state, index: int) -> Asset: url=f"{cls.BASE}/embed/avatars/{index}.png", key=str(index), animated=False, + extension="png", ) @classmethod @@ -191,7 +196,9 @@ def _from_avatar(cls, state, user_id: int, avatar: str) -> Asset: url = f"{cls.BASE}/avatars/{user_id}/{avatar}.{format}?size=1024" if animated: url += "&animated=true" - return cls(state, url=url, key=avatar, animated=animated) + return cls( + state, url=url, key=avatar, animated=animated, extension=format, size=1024 + ) @classmethod def _from_avatar_decoration( @@ -208,6 +215,8 @@ def _from_avatar_decoration( url=f"{cls.BASE}/{endpoint}/{avatar_decoration}.png?size=1024", key=avatar_decoration, animated=animated, + extension="png", + size=1024, ) @classmethod @@ -235,6 +244,8 @@ def _from_user_primary_guild_tag( url=f"{Asset.BASE}/guild-tag-badges/{identity_guild_id}/{badge_id}.png?size=256", key=badge_id, animated=False, + extension="png", + size=256, ) @classmethod @@ -246,7 +257,9 @@ def _from_guild_avatar( url = f"{cls.BASE}/guilds/{guild_id}/users/{member_id}/avatars/{avatar}.{format}?size=1024" if animated: url += "&animated=true" - return cls(state, url=url, key=avatar, animated=animated) + return cls( + state, url=url, key=avatar, animated=animated, extension=format, size=1024 + ) @classmethod def _from_guild_banner( @@ -257,7 +270,9 @@ def _from_guild_banner( url = f"{cls.BASE}/guilds/{guild_id}/users/{member_id}/banners/{banner}.{format}?size=512" if animated: url += "&animated=true" - return cls(state, url=url, key=banner, animated=animated) + return cls( + state, url=url, key=banner, animated=animated, extension=format, size=512 + ) @classmethod def _from_icon(cls, state, object_id: int, icon_hash: str, path: str) -> Asset: @@ -266,6 +281,8 @@ def _from_icon(cls, state, object_id: int, icon_hash: str, path: str) -> Asset: url=f"{cls.BASE}/{path}-icons/{object_id}/{icon_hash}.png?size=1024", key=icon_hash, animated=False, + extension="png", + size=1024, ) @classmethod @@ -275,6 +292,8 @@ def _from_cover_image(cls, state, object_id: int, cover_image_hash: str) -> Asse url=f"{cls.BASE}/app-assets/{object_id}/store/{cover_image_hash}.png?size=1024", key=cover_image_hash, animated=False, + extension="png", + size=1024, ) @classmethod @@ -287,6 +306,7 @@ def _from_collectible( url=f"{cls.BASE}/assets/collectibles/{asset}{name}", key=asset, animated=animated, + extension="webm" if animated else "png", ) @classmethod @@ -300,7 +320,9 @@ def _from_guild_image(cls, state, guild_id: int, image: str, path: str) -> Asset url = f"{cls.BASE}/{path}/{guild_id}/{image}.{format}?size=1024" if animated: url += "&animated=true" - return cls(state, url=url, key=image, animated=animated) + return cls( + state, url=url, key=image, animated=animated, extension=format, size=1024 + ) @classmethod def _from_guild_icon(cls, state, guild_id: int, icon_hash: str) -> Asset: @@ -309,7 +331,14 @@ def _from_guild_icon(cls, state, guild_id: int, icon_hash: str) -> Asset: url = f"{cls.BASE}/icons/{guild_id}/{icon_hash}.{format}?size=1024" if animated: url += "&animated=true" - return cls(state, url=url, key=icon_hash, animated=animated) + return cls( + state, + url=url, + key=icon_hash, + animated=animated, + extension=format, + size=1024, + ) @classmethod def _from_sticker_banner(cls, state, banner: int) -> Asset: @@ -318,6 +347,7 @@ def _from_sticker_banner(cls, state, banner: int) -> Asset: url=f"{cls.BASE}/app-assets/710982414301790216/store/{banner}.png", key=str(banner), animated=False, + extension="png", ) @classmethod @@ -327,7 +357,14 @@ def _from_user_banner(cls, state, user_id: int, banner_hash: str) -> Asset: url = f"{cls.BASE}/banners/{user_id}/{banner_hash}.{format}?size=512" if animated: url += "&animated=true" - return cls(state, url=url, key=banner_hash, animated=animated) + return cls( + state, + url=url, + key=banner_hash, + animated=animated, + extension=format, + size=512, + ) @classmethod def _from_scheduled_event_image( @@ -338,6 +375,7 @@ def _from_scheduled_event_image( url=f"{cls.BASE}/guild-events/{event_id}/{cover_hash}.png", key=cover_hash, animated=False, + extension="png", ) @classmethod @@ -346,6 +384,8 @@ def _from_soundboard_sound(cls, state, sound_id: int) -> Asset: state, url=f"{cls.BASE}/soundboard-sounds/{sound_id}", key=str(sound_id), + extension=None, + size=None, ) def __str__(self) -> str: @@ -375,7 +415,7 @@ def key(self) -> str: return self._key @property - def extension(self) -> str: + def extension(self) -> str | None: """Returns the extension of the asset.""" return self._extension @@ -421,6 +461,9 @@ def replace( url = yarl.URL(self._url) path, _ = os.path.splitext(url.path) + extension = self._extension + new_size = self._size + if format is not MISSING: if self._animated: if format not in VALID_ASSET_FORMATS: @@ -428,29 +471,38 @@ def replace( f"format must be one of {VALID_ASSET_FORMATS}" ) url = url.with_path(f"{path}.{format}") + extension = format elif static_format is MISSING: if format not in VALID_STATIC_FORMATS: raise InvalidArgument( f"format must be one of {VALID_STATIC_FORMATS}" ) url = url.with_path(f"{path}.{format}") - + extension = format if static_format is not MISSING and not self._animated: if static_format not in VALID_STATIC_FORMATS: raise InvalidArgument( f"static_format must be one of {VALID_STATIC_FORMATS}" ) url = url.with_path(f"{path}.{static_format}") - + extension = static_format if size is not MISSING: if not utils.valid_icon_size(size): raise InvalidArgument("size must be a power of 2 between 16 and 4096") url = url.with_query(size=size) + new_size = size else: url = url.with_query(url.raw_query_string) url = str(url) - return Asset(state=self._state, url=url, key=self._key, animated=self._animated) + return Asset( + state=self._state, + url=url, + key=self._key, + animated=self._animated, + extension=extension, + size=new_size, + ) def with_size(self, size: int, /) -> Asset: """Returns a new asset with the specified size. @@ -474,7 +526,14 @@ def with_size(self, size: int, /) -> Asset: raise InvalidArgument("size must be a power of 2 between 16 and 4096") url = str(yarl.URL(self._url).with_query(size=size)) - return Asset(state=self._state, url=url, key=self._key, animated=self._animated) + return Asset( + state=self._state, + url=url, + key=self._key, + animated=self._animated, + extension=self._extension, + size=size, + ) def with_format(self, format: ValidAssetFormatTypes, /) -> Asset: """Returns a new asset with the specified format. @@ -504,7 +563,14 @@ def with_format(self, format: ValidAssetFormatTypes, /) -> Asset: url = yarl.URL(self._url) path, _ = os.path.splitext(url.path) url = str(url.with_path(f"{path}.{format}").with_query(url.raw_query_string)) - return Asset(state=self._state, url=url, key=self._key, animated=self._animated) + return Asset( + state=self._state, + url=url, + key=self._key, + animated=self._animated, + extension=format, + size=self._size, + ) def with_static_format(self, format: ValidStaticFormatTypes, /) -> Asset: """Returns a new asset with the specified static format. From c36015134a7ef9dde4c1c9336b2b2a2759abc5bd Mon Sep 17 00:00:00 2001 From: SilberGecko6917 Date: Sun, 5 Jul 2026 15:00:17 +0200 Subject: [PATCH 7/8] fix typo --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f063feb315..5f3a0567b1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,7 +15,7 @@ These changes are available on the `master` branch, but have not yet been releas - Add `RoleColours.HOLOGRAPHIC_PRIMARY`, `RoleColours.HOLOGRAPHIC_SECONDARY`, and `RoleColours.HOLOGRAPHIC_TERTIARY` class constants. ([#3268](https://github.com/Pycord-Development/pycord/pull/3268)) -- Add `Asset.size`, `Asset.extention` properties. +- Add `Asset.size`, `Asset.extension` properties. ([#3294](https://github.com/Pycord-Development/pycord/pull/3294)) ### Changed From ee12a060b22563e29a944fbe63f4628616d9da20 Mon Sep 17 00:00:00 2001 From: SilberGecko6917 Date: Sun, 5 Jul 2026 19:04:07 +0200 Subject: [PATCH 8/8] review changes --- CHANGELOG.md | 6 +++--- discord/asset.py | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5f3a0567b1..58c97e9c53 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,15 +15,13 @@ These changes are available on the `master` branch, but have not yet been releas - Add `RoleColours.HOLOGRAPHIC_PRIMARY`, `RoleColours.HOLOGRAPHIC_SECONDARY`, and `RoleColours.HOLOGRAPHIC_TERTIARY` class constants. ([#3268](https://github.com/Pycord-Development/pycord/pull/3268)) -- Add `Asset.size`, `Asset.extension` properties. +- Add `Asset.size` and `Asset.extension` properties. ([#3294](https://github.com/Pycord-Development/pycord/pull/3294)) ### Changed ### Fixed -- Fix animated asset url extension from `.gif` to `.webp` - ([#3294](https://github.com/Pycord-Development/pycord/pull/3294)) - Fix an attribute error in `RoleColours.is_holographic()` when `secondary` or `tertiary` is `None`. ([#3268](https://github.com/Pycord-Development/pycord/pull/3268)) @@ -58,6 +56,8 @@ These changes are available on the `master` branch, but have not yet been releas ([#3278](https://github.com/Pycord-Development/pycord/pull/3278)) - Fix `PartialMessage.edit()` to work with `DesignerView`. ([#3237](https://github.com/Pycord-Development/pycord/pull/3237)) +- Fix animated asset url extension from `.gif` to `.webp` + ([#3294](https://github.com/Pycord-Development/pycord/pull/3294)) ### Deprecated diff --git a/discord/asset.py b/discord/asset.py index 3519fa9ec2..5379501386 100644 --- a/discord/asset.py +++ b/discord/asset.py @@ -416,7 +416,7 @@ def key(self) -> str: @property def extension(self) -> str | None: - """Returns the extension of the asset.""" + """Returns the file extension of the asset.""" return self._extension @property