2424"""
2525from __future__ import annotations
2626
27- from typing import TYPE_CHECKING , Optional , TypeVar , Union
27+ from typing import TYPE_CHECKING , Optional , Union , TypeVar , Generic , Callable , List , Any , Dict
2828
29- import discord .abc
29+ import discord .utils
3030
3131if TYPE_CHECKING :
32- from typing_extensions import ParamSpec
33-
34- import discord
35- from discord import Bot
36- from discord .state import ConnectionState
37-
38- from .core import ApplicationCommand , Option
32+ from . import ApplicationCommand , Option
3933 from ..cog import Cog
40- from ..webhook import WebhookMessage
41- from typing import Callable
34+ from ..embeds import Embed
35+ from ..file import File
36+ from ..guild import Guild
37+ from ..interactions import Interaction , InteractionChannel , InteractionResponse , InteractionMessage
38+ from ..member import Member
39+ from ..mentions import AllowedMentions
40+ from ..message import Message
41+ from ..state import ConnectionState
42+ from ..user import User
43+ from ..ui import View
44+ from ..voice_client import VoiceProtocol
45+ from ..webhook import Webhook , WebhookMessage
46+ from typing_extensions import ParamSpec
4247
4348from ..guild import Guild
4449from ..interactions import Interaction , InteractionResponse
5863__all__ = ("ApplicationContext" , "AutocompleteContext" )
5964
6065
61- class ApplicationContext (discord .abc .Messageable ):
66+ MISSING : Any = discord .utils .MISSING
67+
68+ T = TypeVar ("T" )
69+ BotT = TypeVar ("BotT" , bound = "Union[discord.Bot, discord.AutoShardedBot]" )
70+ CogT = TypeVar ("CogT" , bound = "Cog" )
71+
72+ if TYPE_CHECKING :
73+ P = ParamSpec ('P' )
74+ else :
75+ P = TypeVar ('P' )
76+
77+ class ApplicationContext (discord .abc .Messageable , Generic [BotT ]):
6278 """Represents a Discord application command interaction context.
6379
6480 This class is not created manually and is instead passed to application
@@ -76,9 +92,9 @@ class ApplicationContext(discord.abc.Messageable):
7692 The command that this context belongs to.
7793 """
7894
79- def __init__ (self , bot : Bot , interaction : Interaction ):
80- self .bot = bot
81- self .interaction = interaction
95+ def __init__ (self , bot : BotT , interaction : Interaction ) -> None :
96+ self .bot : BotT = bot
97+ self .interaction : Interaction = interaction
8298
8399 # below attributes will be set after initialization
84100 self .command : ApplicationCommand = None # type: ignore
@@ -88,7 +104,7 @@ def __init__(self, bot: Bot, interaction: Interaction):
88104
89105 self ._state : ConnectionState = self .interaction ._state
90106
91- async def _get_channel (self ) -> discord . abc . Messageable :
107+ async def _get_channel (self ) -> Optional [ InteractionChannel ] :
92108 return self .channel
93109
94110 async def invoke (self , command : ApplicationCommand [CogT , P , T ], / , * args : P .args , ** kwargs : P .kwargs ) -> T :
@@ -118,7 +134,7 @@ async def invoke(self, command: ApplicationCommand[CogT, P, T], /, *args: P.args
118134 return await command (self , * args , ** kwargs )
119135
120136 @cached_property
121- def channel (self ):
137+ def channel (self ) -> Optional [ InteractionChannel ] :
122138 return self .interaction .channel
123139
124140 @cached_property
@@ -133,14 +149,6 @@ def guild(self) -> Optional[Guild]:
133149 def guild_id (self ) -> Optional [int ]:
134150 return self .interaction .guild_id
135151
136- @cached_property
137- def locale (self ) -> Optional [str ]:
138- return self .interaction .locale
139-
140- @cached_property
141- def guild_locale (self ) -> Optional [str ]:
142- return self .interaction .guild_locale
143-
144152 @cached_property
145153 def me (self ) -> Union [Member , User ]:
146154 return self .guild .me if self .guild is not None else self .bot .user
@@ -168,6 +176,14 @@ def voice_client(self):
168176 def response (self ) -> InteractionResponse :
169177 return self .interaction .response
170178
179+ @property
180+ def cog (self ) -> Optional [Cog ]:
181+ """Optional[:class:`.Cog`]: Returns the cog associated with this context's command. ``None`` if it does not exist."""
182+ if self .command is None :
183+ return None
184+
185+ return self .command .cog
186+
171187 @property
172188 def respond (self ) -> Callable [..., Union [Interaction , WebhookMessage ]]:
173189 """Callable[..., Union[:class:`~.Interaction`, :class:`~.Webhook`]]: Sends either a response
@@ -195,33 +211,42 @@ def send_followup(self):
195211 f"Interaction was not yet issued a response. Try using { type (self ).__name__ } .respond() first."
196212 )
197213
198- @property
199- def defer (self ) :
200- return self .interaction .response .defer
214+ @discord . utils . copy_doc ( InteractionResponse . defer )
215+ async def defer (self , * , ephemeral : bool = False ) -> None :
216+ return await self .interaction .response .defer ( ephemeral = ephemeral )
201217
202218 @property
203- def followup (self ):
219+ def followup (self ) -> Webhook :
204220 return self .interaction .followup
205221
206- async def delete (self ):
222+ async def delete (self ) -> None :
207223 """Calls :attr:`~discord.commands.ApplicationContext.respond`.
208224 If the response is done, then calls :attr:`~discord.commands.ApplicationContext.respond` first."""
209225 if not self .response .is_done ():
210226 await self .defer ()
211227
212228 return await self .interaction .delete_original_message ()
213229
214- @property
215- def edit (self ):
216- return self .interaction .edit_original_message
217-
218- @property
219- def cog (self ) -> Optional [Cog ]:
220- """Optional[:class:`.Cog`]: Returns the cog associated with this context's command. ``None`` if it does not exist."""
221- if self .command is None :
222- return None
223-
224- return self .command .cog
230+ async def edit (
231+ self ,
232+ * ,
233+ content : Optional [str ] = MISSING ,
234+ embeds : List [Embed ] = MISSING ,
235+ embed : Optional [Embed ] = MISSING ,
236+ file : File = MISSING ,
237+ files : List [File ] = MISSING ,
238+ view : Optional [View ] = MISSING ,
239+ allowed_mentions : Optional [AllowedMentions ] = None ,
240+ ) -> InteractionMessage :
241+ return await self .interaction .edit_original_message (
242+ content = content ,
243+ embeds = embeds ,
244+ embed = embed ,
245+ file = file ,
246+ files = files ,
247+ view = view ,
248+ allowed_mentions = allowed_mentions ,
249+ )
225250
226251
227252class AutocompleteContext :
@@ -248,18 +273,24 @@ class AutocompleteContext:
248273 """
249274
250275 __slots__ = ("bot" , "interaction" , "command" , "focused" , "value" , "options" )
251-
252- def __init__ (self , bot : Bot , interaction : Interaction ) -> None :
253- self .bot = bot
254- self .interaction = interaction
255-
256- self .command : ApplicationCommand = None # type: ignore
257- self .focused : Option = None # type: ignore
258- self .value : str = None # type: ignore
259- self .options : dict = None # type: ignore
276+
277+ def __init__ (
278+ self ,
279+ interaction : Interaction ,
280+ * ,
281+ command : ApplicationCommand ,
282+ focused : Option ,
283+ value : str ,
284+ options : Dict [str , Any ],
285+ ) -> None :
286+ self .interaction : Interaction = interaction
287+ self .command : ApplicationCommand = command
288+ self .focused : Option = focused
289+ self .value : str = value
290+ self .options : Dict [str , Any ] = options
260291
261292 @property
262- def cog (self ) -> Optional [Cog ]:
293+ def cog (self ) -> Optional [CogT ]:
263294 """Optional[:class:`.Cog`]: Returns the cog associated with this context's command. ``None`` if it does not exist."""
264295 if self .command is None :
265296 return None
0 commit comments