37
37
Coroutine ,
38
38
List ,
39
39
Optional ,
40
+ Type ,
40
41
TypeVar ,
41
42
Union ,
42
43
)
53
54
UserCommand ,
54
55
ApplicationCommand ,
55
56
ApplicationContext ,
57
+ AutocompleteContext ,
56
58
command ,
57
59
)
58
60
from .cog import CogMixin
@@ -86,19 +88,23 @@ class ApplicationCommandMixin:
86
88
def __init__ (self , * args , ** kwargs ) -> None :
87
89
super ().__init__ (* args , ** kwargs )
88
90
self ._pending_application_commands = []
89
- self .application_commands = {}
91
+ self ._application_commands = {}
90
92
91
93
@property
92
94
def pending_application_commands (self ):
93
95
return self ._pending_application_commands
94
96
95
97
@property
96
98
def commands (self ) -> List [Union [ApplicationCommand , Any ]]:
97
- commands = list ( self .application_commands . values ())
99
+ commands = self .application_commands
98
100
if self ._supports_prefixed_commands :
99
101
commands += self .prefixed_commands
100
102
return commands
101
103
104
+ @property
105
+ def application_commands (self ) -> List [ApplicationCommand ]:
106
+ return list (self ._application_commands .values ())
107
+
102
108
def add_application_command (self , command : ApplicationCommand ) -> None :
103
109
"""Adds a :class:`.ApplicationCommand` into the internal list of commands.
104
110
@@ -112,7 +118,6 @@ def add_application_command(self, command: ApplicationCommand) -> None:
112
118
command: :class:`.ApplicationCommand`
113
119
The command to add.
114
120
"""
115
-
116
121
if self .debug_guilds and command .guild_ids is None :
117
122
command .guild_ids = self .debug_guilds
118
123
self ._pending_application_commands .append (command )
@@ -136,7 +141,54 @@ def remove_application_command(
136
141
The command that was removed. If the name is not valid then
137
142
``None`` is returned instead.
138
143
"""
139
- return self .application_commands .pop (command .id )
144
+ return self ._application_commands .pop (command .id )
145
+
146
+ @property
147
+ def get_command (self ):
148
+ """Shortcut for :meth:`.get_application_command`.
149
+
150
+ .. note::
151
+ Overridden in :class:`ext.commands.Bot`.
152
+
153
+ .. versionadded:: 2.0
154
+ """
155
+ # TODO: Do something like we did in self.commands for this
156
+ return self .get_application_command
157
+
158
+ def get_application_command (
159
+ self ,
160
+ name : str ,
161
+ guild_ids : Optional [List [int ]] = None ,
162
+ type : Type [ApplicationCommand ] = SlashCommand ,
163
+ ) -> Optional [ApplicationCommand ]:
164
+ """Get a :class:`.ApplicationCommand` from the internal list
165
+ of commands.
166
+
167
+ .. versionadded:: 2.0
168
+
169
+ Parameters
170
+ -----------
171
+ name: :class:`str`
172
+ The name of the command to get.
173
+ guild_ids: List[:class:`int`]
174
+ The guild ids associated to the command to get.
175
+ type: Type[:class:`.ApplicationCommand`]
176
+ The type of the command to get. Defaults to :class:`.SlashCommand`.
177
+
178
+ Returns
179
+ --------
180
+ Optional[:class:`.ApplicationCommand`]
181
+ The command that was requested. If not found, returns ``None``.
182
+ """
183
+
184
+ for command in self ._application_commands .values ():
185
+ if (
186
+ command .name == name
187
+ and isinstance (command , type )
188
+ ):
189
+ if guild_ids is not None and command .guild_ids != guild_ids :
190
+ return
191
+ return command
140
192
141
193
async def sync_commands (self ) -> None :
142
194
"""|coro|
@@ -199,7 +251,7 @@ async def register_commands(self) -> None:
199
251
type = i ["type" ],
200
252
)
201
253
cmd .id = i ["id" ]
202
- self .application_commands [cmd .id ] = cmd
254
+ self ._application_commands [cmd .id ] = cmd
203
255
204
256
# Permissions (Roles will be converted to IDs just before Upsert for Global Commands)
205
257
global_permissions .append ({"id" : i ["id" ], "permissions" : cmd .permissions })
@@ -234,7 +286,7 @@ async def register_commands(self) -> None:
234
286
for i in cmds :
235
287
cmd = find (lambda cmd : cmd .name == i ["name" ] and cmd .type == i ["type" ] and int (i ["guild_id" ]) in cmd .guild_ids , self .pending_application_commands )
236
288
cmd .id = i ["id" ]
237
- self .application_commands [cmd .id ] = cmd
289
+ self ._application_commands [cmd .id ] = cmd
238
290
239
291
# Permissions
240
292
permissions = [
@@ -325,7 +377,7 @@ async def register_commands(self) -> None:
325
377
if len (new_cmd_perm ["permissions" ]) > 10 :
326
378
print (
327
379
"Command '{name}' has more than 10 permission overrides in guild ({guild_id}).\n will only use the first 10 permission overrides." .format (
328
- name = self .application_commands [new_cmd_perm ["id" ]].name ,
380
+ name = self ._application_commands [new_cmd_perm ["id" ]].name ,
329
381
guild_id = guild_id ,
330
382
)
331
383
)
@@ -375,12 +427,14 @@ async def process_application_commands(self, interaction: Interaction) -> None:
375
427
return
376
428
377
429
try :
378
- command = self .application_commands [interaction .data ["id" ]]
430
+ command = self ._application_commands [interaction .data ["id" ]]
379
431
except KeyError :
380
432
self .dispatch ("unknown_command" , interaction )
381
433
else :
382
434
if interaction .type is InteractionType .auto_complete :
383
- return await command .invoke_autocomplete_callback (interaction )
435
+ ctx = await self .get_autocomplete_context (interaction )
436
+ ctx .command = command
437
+ return await command .invoke_autocomplete_callback (ctx )
384
438
385
439
ctx = await self .get_application_context (interaction )
386
440
ctx .command = command
@@ -516,6 +570,37 @@ class be provided, it must be similar enough to
516
570
cls = ApplicationContext
517
571
return cls (self , interaction )
518
572
573
+ async def get_autocomplete_context (
574
+ self , interaction : Interaction , cls = None
575
+ ) -> AutocompleteContext :
576
+ r"""|coro|
577
+
578
+ Returns the autocomplete context from the interaction.
579
+
580
+ This is a more low-level counter-part for :meth:`.process_application_commands`
581
+ to allow users more fine grained control over the processing.
582
+
583
+ Parameters
584
+ -----------
585
+ interaction: :class:`discord.Interaction`
586
+ The interaction to get the invocation context from.
587
+ cls
588
+ The factory class that will be used to create the context.
589
+ By default, this is :class:`.AutocompleteContext`. Should a custom
590
+ class be provided, it must be similar enough to
591
+ :class:`.AutocompleteContext`\'s interface.
592
+
593
+ Returns
594
+ --------
595
+ :class:`.AutocompleteContext`
596
+ The autocomplete context. The type of this can change via the
597
+ ``cls`` parameter.
598
+ """
599
+ if cls is None :
600
+ cls = AutocompleteContext
601
+ return cls (self , interaction )
602
+
603
+
519
604
520
605
class BotBase (ApplicationCommandMixin , CogMixin ):
521
606
_supports_prefixed_commands = False
0 commit comments