27
27
import array
28
28
import asyncio
29
29
import collections .abc
30
+ import datetime
31
+ import functools
32
+ import itertools
33
+ import json
34
+ import re
35
+ import sys
36
+ import types
37
+ import unicodedata
38
+ import warnings
39
+ from base64 import b64encode
40
+ from bisect import bisect_left
41
+ from inspect import isawaitable as _isawaitable , signature as _signature
42
+ from operator import attrgetter
30
43
from typing import (
31
44
Any ,
32
45
AsyncIterator ,
33
46
Callable ,
34
- Coroutine ,
35
47
Dict ,
36
48
ForwardRef ,
37
49
Generic ,
49
61
Union ,
50
62
overload ,
51
63
TYPE_CHECKING ,
64
+ Awaitable ,
52
65
)
53
- import unicodedata
54
- from base64 import b64encode
55
- from bisect import bisect_left
56
- import datetime
57
- import functools
58
- from inspect import isawaitable as _isawaitable , signature as _signature
59
- from operator import attrgetter
60
- import json
61
- import re
62
- import sys
63
- import types
64
- import warnings
65
66
66
67
from .errors import InvalidArgument , HTTPException
67
68
@@ -123,7 +124,6 @@ def __get__(self, instance, owner):
123
124
124
125
125
126
if TYPE_CHECKING :
126
- from functools import cached_property as cached_property
127
127
128
128
from typing_extensions import ParamSpec
129
129
@@ -132,7 +132,7 @@ def __get__(self, instance, owner):
132
132
from .invite import Invite
133
133
from .template import Template
134
134
from .commands .context import AutocompleteContext
135
- from . interactions import Interaction
135
+
136
136
137
137
class _RequestLike (Protocol ):
138
138
headers : Mapping [str , Any ]
@@ -142,6 +142,7 @@ class _RequestLike(Protocol):
142
142
143
143
else :
144
144
cached_property = _cached_property
145
+ AutocompleteContext = Any
145
146
146
147
147
148
T = TypeVar ('T' )
@@ -1057,15 +1058,23 @@ def generate_snowflake(dt: Optional[datetime.datetime] = None) -> int:
1057
1058
return int (dt .timestamp () * 1000 - DISCORD_EPOCH ) << 22 | 0x3fffff
1058
1059
1059
1060
1060
- def basic_autocomplete (values : Union [Iterable [str ],
1061
- Callable [[Interaction ], Union [Iterable [str ], Coroutine [Iterable [str ]]]],
1062
- Coroutine [Iterable [str ]]]) -> Callable [[Interaction , str ], Coroutine [List [str ]]]:
1061
+ V = Union [Iterable [str ], Iterable [int ], Iterable [float ]]
1062
+ AV = Awaitable [V ]
1063
+ Values = Union [V , Callable [[AutocompleteContext ], Union [V , AV ]], AV ]
1064
+ AutocompleteFunc = Callable [[AutocompleteContext ], AV ]
1065
+
1066
+
1067
+ def basic_autocomplete (values : Values ) -> AutocompleteFunc :
1063
1068
"""A helper function to make a basic autocomplete for slash commands. This is a pretty standard autocomplete and
1064
1069
will return any options that start with the value from the user, case insensitive. If :param:`values` is callable,
1065
- it will be called with the interaction .
1070
+ it will be called with the AutocompleteContext .
1066
1071
1067
1072
This is meant to be passed into the :attr:`discord.Option.autocomplete` attribute.
1068
1073
1074
+ Note
1075
+ -----
1076
+ Autocomplete cannot be used for options that have specified choices.
1077
+
1069
1078
Example
1070
1079
--------
1071
1080
@@ -1075,8 +1084,8 @@ def basic_autocomplete(values: Union[Iterable[str],
1075
1084
1076
1085
# or
1077
1086
1078
- async def autocomplete(interaction ):
1079
- return ( "foo", "bar", "baz", interaction.user.name)
1087
+ async def autocomplete(ctx ):
1088
+ return "foo", "bar", "baz", ctx. interaction.user.name
1080
1089
1081
1090
Option(str, "name", autocomplete=basic_autocomplete(autocomplete))
1082
1091
@@ -1085,22 +1094,24 @@ async def autocomplete(interaction):
1085
1094
1086
1095
Parameters
1087
1096
-----------
1088
- values: Union[Iterable[:class:`str`], Callable[[:class:`Interaction `], Union[Iterable[:class:`str`], Coroutine[ Iterable[:class:`str`]]]], Coroutine[ Iterable[:class:`str`]]]
1097
+ values: Union[Union[ Iterable[:class:`str`], Iterable[:class:`int`], Iterable[:class:`float`]], Callable[[:class:`AutocompleteContext `], Union[Union[ Iterable[:class:`str`], Iterable[:class:`int`], Iterable[:class:`float`]], Awaitable[Union[Iterable[:class:` str`], Iterable[:class:`int`], Iterable[:class:`float`]]]]], Awaitable[Union[ Iterable[:class:`str`], Iterable[:class:`int`], Iterable[:class:`float`] ]]]
1089
1098
Possible values for the option. Accepts an iterable of :class:`str`, a callable (sync or async) that takes a
1090
- single argument of :class:`Interaction `, or a coroutine. Must resolve to an iterable of :class:`str`.
1099
+ single argument of :class:`AutocompleteContext `, or a coroutine. Must resolve to an iterable of :class:`str`.
1091
1100
1092
1101
Returns
1093
1102
--------
1094
- Callable[[:class:`Interaction`, :class:`str`], Coroutine[List [:class:`str` ]]]
1103
+ Callable[[:class:`AutocompleteContext`], Awaitable[Union[Iterable[ :class:`str`], Iterable[:class:`int`], Iterable [:class:`float`] ]]]
1095
1104
A wrapped callback for the autocomplete.
1096
1105
"""
1097
- async def autocomplete_callback (ctx : AutocompleteContext ) -> List [ str ] :
1106
+ async def autocomplete_callback (ctx : AutocompleteContext ) -> V :
1098
1107
_values = values # since we reassign later, python considers it local if we don't do this
1099
1108
1100
1109
if callable (_values ):
1101
- _values = _values (interaction )
1110
+ _values = _values (ctx )
1102
1111
if asyncio .iscoroutine (_values ):
1103
1112
_values = await _values
1104
- return ([x for x in _values if x .lower ().startswith (ctx .value .lower ())])[:25 ]
1113
+
1114
+ gen = (val for val in _values if str (val ).lower ().startswith (str (ctx .value or "" ).lower ()))
1115
+ return iter (itertools .islice (gen , 25 ))
1105
1116
1106
1117
return autocomplete_callback
0 commit comments