Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
Show all changes
142 commits
Select commit Hold shift + click to select a range
dce0206
Update CHANGELOG.md
Lumabots May 2, 2025
b2b8884
add a get or fetch to guild
Lumabots May 3, 2025
8f9a257
Implement better get_or_fetch using typevar and object
Lumabots May 3, 2025
9f6219c
shortcut for get or fetch
Lumabots May 3, 2025
4af5149
Update CHANGELOG.md
Lumabots May 3, 2025
6f59fcd
style(pre-commit): auto fixes from pre-commit.com hooks
pre-commit-ci[bot] May 3, 2025
c0689cc
usage of subclass
Lumabots May 3, 2025
b20822a
style(pre-commit): auto fixes from pre-commit.com hooks
pre-commit-ci[bot] May 3, 2025
4a363f5
add get_emoji method
Lumabots May 3, 2025
c3a7dd2
style(pre-commit): auto fixes from pre-commit.com hooks
pre-commit-ci[bot] May 3, 2025
e614c47
add get_or_fetch_emoji method
Lumabots May 3, 2025
0c0a042
shortcut getorfetch client + removal of get_or_fetch user in favor of…
Lumabots May 4, 2025
466e41b
style(pre-commit): auto fixes from pre-commit.com hooks
pre-commit-ci[bot] May 4, 2025
388a234
Update utils.py
Lumabots May 4, 2025
9737f69
Update guild.py
Lumabots May 4, 2025
656de14
Update client.py
Lumabots May 4, 2025
461eab7
style(pre-commit): auto fixes from pre-commit.com hooks
pre-commit-ci[bot] May 4, 2025
b6f8878
Update utils.py
Lumabots May 4, 2025
f2a7d72
style(pre-commit): auto fixes from pre-commit.com hooks
pre-commit-ci[bot] May 4, 2025
5d68207
add utils.deprecated
Lumabots May 4, 2025
4ca87d8
style(pre-commit): auto fixes from pre-commit.com hooks
pre-commit-ci[bot] May 4, 2025
9903fb7
add warning
Lumabots May 4, 2025
a1ec6f9
style(pre-commit): auto fixes from pre-commit.com hooks
pre-commit-ci[bot] May 4, 2025
47de080
Update client.py
Lumabots May 4, 2025
4430825
added backward support
Lumabots May 5, 2025
010cc78
style(pre-commit): auto fixes from pre-commit.com hooks
pre-commit-ci[bot] May 5, 2025
368a55d
fixed missing coma
Lumabots May 5, 2025
76c56a8
ig im drunk
Lumabots May 5, 2025
811682d
fix my drunkness
Lumabots May 5, 2025
a102d5d
style(pre-commit): auto fixes from pre-commit.com hooks
pre-commit-ci[bot] May 5, 2025
528b84b
now im not drunk
Lumabots May 5, 2025
7e766be
Update utils.py
Lumabots May 5, 2025
f6b8e18
style(pre-commit): auto fixes from pre-commit.com hooks
pre-commit-ci[bot] May 5, 2025
a5deffe
Update utils.py
Lumabots May 5, 2025
fff74c4
Update utils.py
Lumabots May 5, 2025
9e45627
style(pre-commit): auto fixes from pre-commit.com hooks
pre-commit-ci[bot] May 5, 2025
0baae1d
usage of abc
Lumabots May 5, 2025
a3aeb4b
style(pre-commit): auto fixes from pre-commit.com hooks
pre-commit-ci[bot] May 5, 2025
2404d9c
_EmojiTag
Lumabots May 5, 2025
23409a7
style(pre-commit): auto fixes from pre-commit.com hooks
pre-commit-ci[bot] May 5, 2025
8f278f8
Update utils.py
Lumabots May 5, 2025
6d5be54
style(pre-commit): auto fixes from pre-commit.com hooks
pre-commit-ci[bot] May 5, 2025
11fbbc9
Update utils.py
Lumabots May 9, 2025
590339a
Merge branch 'master' into get_or_fetch
Lumabots May 9, 2025
267d574
Update discord/client.py
Lumabots May 9, 2025
dc45449
add the raise error
Lumabots May 9, 2025
f22d8a2
Update discord/utils.py
Lumabots May 9, 2025
cbb7951
Update utils.pyfix missing appemoji
Lumabots May 9, 2025
fdbb7d3
style(pre-commit): auto fixes from pre-commit.com hooks
pre-commit-ci[bot] May 9, 2025
5b35d95
add missing raise to doc
Lumabots May 9, 2025
b8a8628
refactor: add TODO comments for removal of deprecated arguments in ge…
Lumabots May 9, 2025
ba5541e
refactor: move _FETCHABLE type variable to utils for better accessibi…
Lumabots May 9, 2025
5421a3f
fix: update import statement for _FETCHABLE from utils module
Lumabots May 9, 2025
50318c2
refactor: streamline get_or_fetch logic with a mapping for object types
Lumabots May 9, 2025
541e668
fix: add validation for Guild type in get_or_fetch function
Lumabots May 9, 2025
b20cffb
fix: correct base type resolution in get_or_fetch function
Lumabots May 9, 2025
3e94a4f
fix: add Role type support in get_or_fetch function
Lumabots May 14, 2025
7384d7c
fix: update role retrieval methods in get_or_fetch function
Lumabots May 14, 2025
b832b55
Merge branch 'master' into get_or_fetch
Lumabots May 14, 2025
0ffaa4b
Update CHANGELOG.md
Lumabots May 15, 2025
92d2987
style(pre-commit): auto fixes from pre-commit.com hooks
pre-commit-ci[bot] May 15, 2025
b8c7f7f
Update CHANGELOG.md
Lumabots May 17, 2025
53dc93c
style(pre-commit): auto fixes from pre-commit.com hooks
pre-commit-ci[bot] May 17, 2025
6d89376
Update CHANGELOG.md
Lumabots May 17, 2025
e2e8b3d
style(pre-commit): auto fixes from pre-commit.com hooks
pre-commit-ci[bot] May 17, 2025
2abfba2
Update CHANGELOG.md
Lumabots May 18, 2025
fb9e077
Merge branch 'master' into get_or_fetch
Lumabots May 20, 2025
c60fbab
feat: update get_or_fetch method to accept Optional[int] for object_id
Lumabots Jun 6, 2025
29863f4
Merge branch 'master' into get_or_fetch
Lumabots Jun 6, 2025
4a5eca4
fix: "MISSING" not being exported
Lumabots Jun 14, 2025
2ed0de6
Merge branch 'master' into get_or_fetch
Lumabots Jun 20, 2025
0c99851
Merge branch 'master' into get_or_fetch
Lumabots Jun 28, 2025
dffef1f
Merge branch 'master' into get_or_fetch
Lumabots Jul 13, 2025
f81a338
add some more comment
Lumabots Jul 13, 2025
cc273c2
Update utils.py
Lumabots Jul 13, 2025
0302fcd
Merge branch 'master' into get_or_fetch
Lumabots Jul 22, 2025
2837e94
style(pre-commit): auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jul 22, 2025
1149c0a
Merge branch 'master' into get_or_fetch
Lumabots Aug 2, 2025
16fda2a
Merge branch 'master' into get_or_fetch
Lulalaby Aug 2, 2025
b70c666
Update discord/utils.py
Lumabots Aug 2, 2025
198556d
Update discord/utils.py
Lumabots Aug 2, 2025
91b3d68
comment
Lumabots Aug 2, 2025
cb38bd7
style(pre-commit): auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Aug 2, 2025
f13e86c
fix docs
Lumabots Aug 2, 2025
543dec8
Merge branch 'get_or_fetch' of https://github.com/Lumabots/pycord int…
Lumabots Aug 2, 2025
da59485
Update discord/client.py
Lumabots Aug 2, 2025
fa0efba
usage of literal None
Lumabots Aug 2, 2025
b6ff5f3
Merge branch 'get_or_fetch' of https://github.com/Lumabots/pycord int…
Lumabots Aug 2, 2025
7d12503
style(pre-commit): auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Aug 2, 2025
77b2a18
Merge branch 'master' into get_or_fetch
Lumabots Aug 3, 2025
d0c524c
return None when fetching fails
Lumabots Aug 3, 2025
ddf2248
Merge branch 'get_or_fetch' of https://github.com/Lumabots/pycord int…
Lumabots Aug 3, 2025
6c6e33a
style(pre-commit): auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Aug 3, 2025
ea555a1
back to non breaking
Lumabots Aug 3, 2025
e0a4745
Merge branch 'get_or_fetch' of https://github.com/Lumabots/pycord int…
Lumabots Aug 3, 2025
6db3f56
style(pre-commit): auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Aug 3, 2025
59768c1
Merge branch 'master' into get_or_fetch
Lumabots Aug 3, 2025
890cc53
Update discord/utils.py
Lumabots Aug 3, 2025
f6d6206
Update CHANGELOG.md
Lumabots Aug 3, 2025
d6daa2d
style(pre-commit): auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Aug 3, 2025
11035ec
paillat suggestions, in test
Lumabots Aug 3, 2025
8094315
Merge branch 'get_or_fetch' of https://github.com/Lumabots/pycord int…
Lumabots Aug 3, 2025
2d7fb85
fix bug invalid data unhandle
Lumabots Aug 17, 2025
0ab70fd
style(pre-commit): auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Aug 17, 2025
3dba8a5
Merge branch 'master' into get_or_fetch
Lumabots Aug 30, 2025
3b98cac
style(pre-commit): auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Aug 30, 2025
8976a32
Merge branch 'master' into get_or_fetch
Lumabots Aug 30, 2025
c966f50
style(pre-commit): auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Aug 30, 2025
8028be1
Merge branch 'master' into get_or_fetch
Lulalaby Sep 1, 2025
9e9f5e7
fix: changelog entry position
Lulalaby Sep 1, 2025
5151f0e
Merge branch 'master' into get_or_fetch
Lumabots Sep 1, 2025
d97ae72
Merge branch 'master' into get_or_fetch
Lulalaby Sep 1, 2025
d48a149
Merge branch 'master' into get_or_fetch
Soheab Sep 4, 2025
6c40af9
style(pre-commit): auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Sep 4, 2025
4a6cde0
docs rewrits
Lumabots Sep 6, 2025
5325b25
Merge branch 'master' into get_or_fetch
Lumabots Sep 6, 2025
c376327
Merge branch 'master' into get_or_fetch
Lumabots Sep 8, 2025
a446fa7
Update guild.py
Lumabots Sep 10, 2025
c7edcf3
Update guild.py
Lumabots Sep 10, 2025
58d355f
Update utils.py
Lumabots Sep 10, 2025
adf9fbf
Update CHANGELOG.md
Lumabots Sep 10, 2025
77523d0
Merge branch 'master' into get_or_fetch
Lumabots Sep 17, 2025
18f7dcf
Update discord/client.py
Lumabots Sep 18, 2025
6648fd5
fix copilot mistakes
Lumabots Sep 18, 2025
c4c5459
fix
Lumabots Sep 18, 2025
7c07ab9
Merge branch 'get_or_fetch' of https://github.com/Lumabots/pycord int…
Lumabots Sep 18, 2025
ae36e61
style(pre-commit): auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Sep 18, 2025
154d98a
usage of type for specification
Lumabots Sep 21, 2025
3c6b526
style(pre-commit): auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Sep 21, 2025
53c1e65
Merge branch 'master' into get_or_fetch
Lumabots Oct 10, 2025
58b92f3
Update discord/utils.py
Lumabots Oct 11, 2025
6240173
fix: :bug: Prevent `InvalidArgument` for `AppEmoji` in `get_or_fetch`…
Lumabots Oct 11, 2025
9fdcad4
fix: :bug: Import `AppEmoji` in `get_or_fetch` to resolve potential i…
Lumabots Oct 11, 2025
316e07d
style(pre-commit): auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Oct 11, 2025
e068605
Merge branch 'master' into get_or_fetch
Paillat-dev Oct 19, 2025
10b5bbd
Update CHANGELOG.md
Lumabots Oct 19, 2025
3c89f07
Update utils.py
Lumabots Oct 19, 2025
2b14ece
style(pre-commit): auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Oct 19, 2025
82e11f3
fix: :bug: Import `AppEmoji` in `_get_string_to_type_map` for type ma…
Lumabots Oct 19, 2025
c3173e9
Merge branch 'get_or_fetch' of https://github.com/Lumabots/pycord int…
Lumabots Oct 19, 2025
915e164
style(pre-commit): auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Oct 19, 2025
228bb4a
Merge branch 'master' into get_or_fetch
Lulalaby Oct 20, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ These changes are available on the `master` branch, but have not yet been releas
([#2714](https://github.com/Pycord-Development/pycord/pull/2714))
- Added the ability to pass a `datetime.time` object to `format_dt`
([#2747](https://github.com/Pycord-Development/pycord/pull/2747))
- Added `Guild.get_or_fetch()` shortcut method and better get_or_fetch
([#2776](https://github.com/Pycord-Development/pycord/pull/2776))

### Fixed

Expand Down
44 changes: 44 additions & 0 deletions discord/guild.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@
Optional,
Sequence,
Tuple,
Type,
TypeVar,
Union,
overload,
)
Expand Down Expand Up @@ -863,6 +865,48 @@ def get_member(self, user_id: int, /) -> Member | None:
"""
return self._members.get(user_id)

_FETCHABLE = TypeVar(
"_FETCHABLE",
bound=Union[
VoiceChannel,
TextChannel,
ForumChannel,
StageChannel,
CategoryChannel,
Thread,
Member,
],
)

async def get_or_fetch(
self: Guild,
object_type: type[_FETCHABLE],
object_id: int,
default: Any = MISSING,
) -> _FETCHABLE | None:
"""Shortcut method to get data from guild object either by returning the cached version, or if it does not exist, attempt to fetch it from the api.

Parameters
----------
object_type: Union[:class:`VoiceChannel`, :class:`TextChannel`, :class:`ForumChannel`, :class:`StageChannel`, :class:`CategoryChannel`, :class:`Thread`, :class:`Member`]
Type of object to fetch or get.

object_id: :class:`int`
ID of object to get.

default : Any, optional
A default to return instead of raising if fetch fails.

Returns
-------

Optional[Union[:class:`VoiceChannel`, :class:`TextChannel`, :class:`ForumChannel`, :class:`StageChannel`, :class:`CategoryChannel`, :class:`Thread`, :class:`Member`]]
The object of type that was specified or ``None`` if not found.
"""
return await utils.get_or_fetch(
obj=self, object_type=object_type, object_id=object_id, default=default
)

@property
def premium_subscribers(self) -> list[Member]:
"""A list of members who have "boosted" this guild."""
Expand Down
122 changes: 78 additions & 44 deletions discord/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,13 +56,29 @@
Iterator,
Literal,
Mapping,
Optional,
Protocol,
Sequence,
Type,
TypeVar,
Union,
overload,
)

if TYPE_CHECKING:
from discord import (
Client,
VoiceChannel,
TextChannel,
ForumChannel,
StageChannel,
CategoryChannel,
Thread,
Member,
User,
Guild,
)

from .errors import HTTPException, InvalidArgument

try:
Expand Down Expand Up @@ -573,64 +589,82 @@ def get(iterable: Iterable[T], **attrs: Any) -> T | None:
return None


async def get_or_fetch(obj, attr: str, id: int, *, default: Any = MISSING) -> Any:
"""|coro|
_FETCHABLE = TypeVar(
"_FETCHABLE",
bound=Union[
VoiceChannel,
TextChannel,
ForumChannel,
StageChannel,
CategoryChannel,
Thread,
Member,
User,
Guild,
],
)

Attempts to get an attribute from the object in cache. If it fails, it will attempt to fetch it.
If the fetch also fails, an error will be raised.

async def get_or_fetch(
obj: Guild | Client,
object_type: type[_FETCHABLE],
object_id: int,
default: Any = MISSING,
) -> _FETCHABLE | None:
"""
Shortcut method to get data from guild object either by returning the cached version, or if it does not exist, attempt to fetch it from the api.

Parameters
----------
obj: Any
The object to use the get or fetch methods in
attr: :class:`str`
The attribute to get or fetch. Note the object must have both a ``get_`` and ``fetch_`` method for this attribute.
id: :class:`int`
The ID of the object
default: Any
The default value to return if the object is not found, instead of raising an error.
obj : Guild | Client
The object to operate on.
object_type: Union[:class:`VoiceChannel`, :class:`TextChannel`, :class:`ForumChannel`, :class:`StageChannel`, :class:`CategoryChannel`, :class:`Thread`, :class:`Member`]
Type of object to fetch or get.

Returns
-------
Any
The object found or the default value.

Raises
------
:exc:`AttributeError`
The object is missing a ``get_`` or ``fetch_`` method
:exc:`NotFound`
Invalid ID for the object
:exc:`HTTPException`
An error occurred fetching the object
:exc:`Forbidden`
You do not have permission to fetch the object
object_id: :class:`int`
ID of object to get.

Examples
--------
default : Any, optional
A default to return instead of raising if fetch fails.

Getting a guild from a guild ID: ::
Returns
-------

guild = await utils.get_or_fetch(client, 'guild', guild_id)
Optional[Union[:class:`VoiceChannel`, :class:`TextChannel`, :class:`ForumChannel`, :class:`StageChannel`, :class:`CategoryChannel`, :class:`Thread`, :class:`Member`]]
The object of type that was specified or ``None`` if not found.
"""
if object_type.__name__ in {"Member", "User", "Guild"}:
attr = object_type.__name__.lower()
elif object_type.__name__ in {
"VoiceChannel",
"TextChannel",
"ForumChannel",
"StageChannel",
"CategoryChannel",
"Thread",
}:
attr = "channel"
else:
raise InvalidArgument(
f"Class {object_type.__name__} cannot be used with discord.{type(obj).__name__}.get_or_fetch()"
)

Getting a channel from the guild. If the channel is not found, return None: ::
getter = getattr(obj, f"get_{attr}", None)
if getter:
result = getter(object_id)
if result is not None:
return result

channel = await utils.get_or_fetch(guild, 'channel', channel_id, default=None)
"""
getter = getattr(obj, f"get_{attr}")(id)
if getter is None:
fetcher = getattr(obj, f"fetch_{attr}", None) or getattr(
obj, f"_fetch_{attr}", None
)
if fetcher:
try:
getter = await getattr(obj, f"fetch_{attr}")(id)
except AttributeError:
getter = await getattr(obj, f"_fetch_{attr}")(id)
if getter is None:
raise ValueError(f"Could not find {attr} with id {id} on {obj}")
return await fetcher(object_id)
except (HTTPException, ValueError):
if default is not MISSING:
return default
else:
raise
return getter
raise


def _unique(iterable: Iterable[T]) -> list[T]:
Expand Down