26
26
27
27
import inspect
28
28
import logging
29
+ from collections .abc import Awaitable , Callable , Iterable
29
30
from enum import Enum
30
- from typing import TYPE_CHECKING , Iterable , Literal , Optional , Type , Union
31
+ from typing import TYPE_CHECKING , Any , Literal , Optional , Type , TypeVar , Union
31
32
32
33
from ..abc import GuildChannel , Mentionable
33
34
from ..channel import (
46
47
from ..utils import MISSING , basic_autocomplete
47
48
48
49
if TYPE_CHECKING :
50
+ from ..cog import Cog
49
51
from ..ext .commands import Converter
50
52
from ..member import Member
51
53
from ..message import Attachment
71
73
Type [DiscordEnum ],
72
74
]
73
75
76
+ AutocompleteReturnType = Union [
77
+ Iterable ["OptionChoice" ], Iterable [str ], Iterable [int ], Iterable [float ]
78
+ ]
79
+ T = TypeVar ("T" , bound = AutocompleteReturnType )
80
+ MaybeAwaitable = Union [T , Awaitable [T ]]
81
+ AutocompleteFunction = Union [
82
+ Callable [[AutocompleteContext ], MaybeAwaitable [AutocompleteReturnType ]],
83
+ Callable [[Cog , AutocompleteContext ], MaybeAwaitable [AutocompleteReturnType ]],
84
+ Callable [
85
+ [AutocompleteContext , Any ], # pyright: ignore [reportExplicitAny]
86
+ MaybeAwaitable [AutocompleteReturnType ],
87
+ ],
88
+ Callable [
89
+ [Cog , AutocompleteContext , Any ], # pyright: ignore [reportExplicitAny]
90
+ MaybeAwaitable [AutocompleteReturnType ],
91
+ ],
92
+ ]
93
+
94
+
74
95
__all__ = (
75
96
"ThreadOption" ,
76
97
"Option" ,
@@ -111,11 +132,6 @@ def __init__(self, thread_type: Literal["public", "private", "news"]):
111
132
self ._type = type_map [thread_type ]
112
133
113
134
114
- AutocompleteReturnType = Union [
115
- Iterable ["OptionChoice" ], Iterable [str ], Iterable [int ], Iterable [float ]
116
- ]
117
-
118
-
119
135
class Option :
120
136
"""Represents a selectable option for a slash command.
121
137
@@ -268,7 +284,7 @@ def __init__(
268
284
)
269
285
self .default = kwargs .pop ("default" , None )
270
286
271
- self ._autocomplete = None
287
+ self ._autocomplete : AutocompleteFunction | None = None
272
288
self .autocomplete = kwargs .pop ("autocomplete" , None )
273
289
if len (enum_choices ) > 25 :
274
290
self .choices : list [OptionChoice ] = []
@@ -388,22 +404,17 @@ def __repr__(self):
388
404
return f"<discord.commands.{ self .__class__ .__name__ } name={ self .name } >"
389
405
390
406
@property
391
- def autocomplete (self ):
407
+ def autocomplete (self ) -> AutocompleteFunction | None :
392
408
"""
393
409
The autocomplete handler for the option. Accepts a callable (sync or async)
394
- that takes a single required argument of :class:`AutocompleteContext`.
410
+ that takes a single required argument of :class:`AutocompleteContext` or two arguments
411
+ of :class:`discord.Cog` (being the command's cog) and :class:`AutocompleteContext`.
395
412
The callable must return an iterable of :class:`str` or :class:`OptionChoice`.
396
413
Alternatively, :func:`discord.utils.basic_autocomplete` may be used in place of the callable.
397
414
398
415
Returns
399
416
-------
400
- Union[
401
- Callable[[Self, AutocompleteContext, Any], AutocompleteReturnType],
402
- Callable[[AutocompleteContext, Any], AutocompleteReturnType],
403
- Callable[[Self, AutocompleteContext, Any], Awaitable[AutocompleteReturnType]],
404
- Callable[[AutocompleteContext, Any], Awaitable[AutocompleteReturnType]],
405
- None
406
- ]
417
+ Optional[AutocompleteFunction]
407
418
408
419
.. versionchanged:: 2.7
409
420
@@ -413,17 +424,17 @@ def autocomplete(self):
413
424
return self ._autocomplete
414
425
415
426
@autocomplete .setter
416
- def autocomplete (self , value ) -> None :
427
+ def autocomplete (self , value : AutocompleteFunction | None ) -> None :
417
428
self ._autocomplete = value
418
429
# this is done here so it does not have to be computed every time the autocomplete is invoked
419
430
if self ._autocomplete is not None :
420
- self ._autocomplete ._is_instance_method = (
431
+ self ._autocomplete ._is_instance_method = ( # pyright: ignore [reportFunctionMemberAccess]
421
432
sum (
422
433
1
423
434
for param in inspect .signature (
424
- self .autocomplete
435
+ self ._autocomplete
425
436
).parameters .values ()
426
- if param .default == param .empty
437
+ if param .default == param .empty # pyright: ignore[reportAny]
427
438
and param .kind not in (param .VAR_POSITIONAL , param .VAR_KEYWORD )
428
439
)
429
440
== 2
0 commit comments