3131import sys
3232import traceback
3333from types import TracebackType
34- from typing import TYPE_CHECKING , Any , Callable , Coroutine , Generator , Sequence , TypeVar
34+ from typing import (
35+ TYPE_CHECKING ,
36+ Any ,
37+ Callable ,
38+ Coroutine ,
39+ Generator ,
40+ Sequence ,
41+ TypeVar ,
42+ )
3543
3644import aiohttp
3745
5967from .sticker import GuildSticker , StandardSticker , StickerPack , _sticker_factory
6068from .template import Template
6169from .threads import Thread
62- from .ui .view import View
70+ from .ui .view import BaseView
6371from .user import ClientUser , User
64- from .utils import MISSING
72+ from .utils import _D , _FETCHABLE , MISSING
6573from .voice_client import VoiceClient
6674from .webhook import Webhook
6775from .widget import Widget
6876
6977if TYPE_CHECKING :
7078 from .abc import GuildChannel , PrivateChannel , Snowflake , SnowflakeTime
71- from .channel import DMChannel
79+ from .channel import (
80+ CategoryChannel ,
81+ DMChannel ,
82+ ForumChannel ,
83+ StageChannel ,
84+ TextChannel ,
85+ VoiceChannel ,
86+ )
7287 from .interactions import Interaction
7388 from .member import Member
7489 from .message import Message
7590 from .poll import Poll
7691 from .soundboard import SoundboardSound
77- from .ui .item import Item
92+ from .threads import Thread , ThreadMember
93+ from .ui .item import Item , ViewItem
7894 from .voice_client import VoiceProtocol
7995
8096__all__ = ("Client" ,)
@@ -546,19 +562,19 @@ async def on_error(self, event_method: str, *args: Any, **kwargs: Any) -> None:
546562 traceback .print_exc ()
547563
548564 async def on_view_error (
549- self , error : Exception , item : Item , interaction : Interaction
565+ self , error : Exception , item : ViewItem , interaction : Interaction
550566 ) -> None :
551567 """|coro|
552568
553569 The default view error handler provided by the client.
554570
555- This only fires for a view if you did not define its :func:`~discord.ui.View .on_error`.
571+ This only fires for a view if you did not define its :func:`~discord.ui.BaseView .on_error`.
556572
557573 Parameters
558574 ----------
559575 error: :class:`Exception`
560576 The exception that was raised.
561- item: :class:`Item `
577+ item: :class:`ViewItem `
562578 The item that the user interacted with.
563579 interaction: :class:`Interaction`
564580 The interaction that was received.
@@ -1165,7 +1181,12 @@ def get_all_members(self) -> Generator[Member]:
11651181 for guild in self .guilds :
11661182 yield from guild .members
11671183
1168- async def get_or_fetch_user (self , id : int , / ) -> User | None :
1184+ @utils .deprecated (
1185+ instead = "Client.get_or_fetch(User, id)" ,
1186+ since = "2.7" ,
1187+ removed = "3.0" ,
1188+ )
1189+ async def get_or_fetch_user (self , id : int , / ) -> User | None : # TODO: Remove in 3.0
11691190 """|coro|
11701191
11711192 Looks up a user in the user cache or fetches if not found.
@@ -1181,7 +1202,49 @@ async def get_or_fetch_user(self, id: int, /) -> User | None:
11811202 The user or ``None`` if not found.
11821203 """
11831204
1184- return await utils .get_or_fetch (obj = self , attr = "user" , id = id , default = None )
1205+ return await self .get_or_fetch (object_type = User , object_id = id , default = None )
1206+
1207+ async def get_or_fetch (
1208+ self : Client ,
1209+ object_type : type [_FETCHABLE ],
1210+ object_id : int | None ,
1211+ default : _D = None ,
1212+ ) -> _FETCHABLE | _D | None :
1213+ """
1214+ Shortcut method to get data from an object either by returning the cached version, or if it does not exist, attempting to fetch it from the API.
1215+
1216+ Parameters
1217+ ----------
1218+ object_type: Type[:class:`VoiceChannel` | :class:`TextChannel` | :class:`ForumChannel` | :class:`StageChannel` | :class:`CategoryChannel` | :class:`Thread` | :class:`User` | :class:`Guild` | :class:`GuildEmoji` | :class:`AppEmoji`]
1219+ Type of object to fetch or get.
1220+
1221+ object_id: :class:`int` | :data:`None`
1222+ ID of object to get. If :data:`None`, returns `default` if provided, else :data:`None`.
1223+
1224+ default: Any | :data:`None`
1225+ A default to return instead of raising if fetch fails.
1226+
1227+ Returns
1228+ -------
1229+ :class:`VoiceChannel` | :class:`TextChannel` | :class:`ForumChannel` | :class:`StageChannel` | :class:`CategoryChannel` | :class:`Thread` | :class:`User` | :class:`Guild` | :class:`GuildEmoji` | :class:`AppEmoji` | :data:`None`
1230+ The object if found, or `default` if provided when not found.
1231+
1232+ Raises
1233+ ------
1234+ :exc:`TypeError`
1235+ Raised when required parameters are missing or invalid types are provided.
1236+ :exc:`InvalidArgument`
1237+ Raised when an unsupported or incompatible object type is used.
1238+ """
1239+ try :
1240+ return await utils .get_or_fetch (
1241+ obj = self ,
1242+ object_type = object_type ,
1243+ object_id = object_id ,
1244+ default = default ,
1245+ )
1246+ except (HTTPException , ValueError , InvalidData ):
1247+ return default
11851248
11861249 # listeners/waiters
11871250
@@ -2037,8 +2100,8 @@ async def create_dm(self, user: Snowflake) -> DMChannel:
20372100 data = await state .http .start_private_message (user .id )
20382101 return state .add_dm_channel (data )
20392102
2040- def add_view (self , view : View , * , message_id : int | None = None ) -> None :
2041- """Registers a :class:`~discord.ui.View ` for persistent listening.
2103+ def add_view (self , view : BaseView , * , message_id : int | None = None ) -> None :
2104+ """Registers a :class:`~discord.ui.BaseView ` for persistent listening.
20422105
20432106 This method should be used for when a view is comprised of components
20442107 that last longer than the lifecycle of the program.
@@ -2047,7 +2110,7 @@ def add_view(self, view: View, *, message_id: int | None = None) -> None:
20472110
20482111 Parameters
20492112 ----------
2050- view: :class:`discord.ui.View `
2113+ view: :class:`discord.ui.BaseView `
20512114 The view to register for dispatching.
20522115 message_id: Optional[:class:`int`]
20532116 The message ID that the view is attached to. This is currently used to
@@ -2063,8 +2126,8 @@ def add_view(self, view: View, *, message_id: int | None = None) -> None:
20632126 and all their components have an explicitly provided ``custom_id``.
20642127 """
20652128
2066- if not isinstance (view , View ):
2067- raise TypeError (f"expected an instance of View not { view .__class__ !r} " )
2129+ if not isinstance (view , BaseView ):
2130+ raise TypeError (f"expected an instance of BaseView not { view .__class__ !r} " )
20682131
20692132 if not view .is_persistent ():
20702133 raise ValueError (
@@ -2075,7 +2138,7 @@ def add_view(self, view: View, *, message_id: int | None = None) -> None:
20752138 self ._connection .store_view (view , message_id )
20762139
20772140 @property
2078- def persistent_views (self ) -> Sequence [View ]:
2141+ def persistent_views (self ) -> Sequence [BaseView ]:
20792142 """A sequence of persistent views added to the client.
20802143
20812144 .. versionadded:: 2.0
0 commit comments