Skip to content

Commit e00b272

Browse files
authored
Merge pull request #476 from BobDotCom/basic-autocomplete
Fix merge errors in utils.basic_autocomplete
2 parents 5a8acf2 + 953eda2 commit e00b272

File tree

1 file changed

+38
-27
lines changed

1 file changed

+38
-27
lines changed

discord/utils.py

Lines changed: 38 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,23 @@
2727
import array
2828
import asyncio
2929
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
3043
from typing import (
3144
Any,
3245
AsyncIterator,
3346
Callable,
34-
Coroutine,
3547
Dict,
3648
ForwardRef,
3749
Generic,
@@ -49,19 +61,8 @@
4961
Union,
5062
overload,
5163
TYPE_CHECKING,
64+
Awaitable,
5265
)
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
6566

6667
from .errors import InvalidArgument, HTTPException
6768

@@ -123,7 +124,6 @@ def __get__(self, instance, owner):
123124

124125

125126
if TYPE_CHECKING:
126-
from functools import cached_property as cached_property
127127

128128
from typing_extensions import ParamSpec
129129

@@ -132,7 +132,7 @@ def __get__(self, instance, owner):
132132
from .invite import Invite
133133
from .template import Template
134134
from .commands.context import AutocompleteContext
135-
from .interactions import Interaction
135+
136136

137137
class _RequestLike(Protocol):
138138
headers: Mapping[str, Any]
@@ -142,6 +142,7 @@ class _RequestLike(Protocol):
142142

143143
else:
144144
cached_property = _cached_property
145+
AutocompleteContext = Any
145146

146147

147148
T = TypeVar('T')
@@ -1057,15 +1058,23 @@ def generate_snowflake(dt: Optional[datetime.datetime] = None) -> int:
10571058
return int(dt.timestamp() * 1000 - DISCORD_EPOCH) << 22 | 0x3fffff
10581059

10591060

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:
10631068
"""A helper function to make a basic autocomplete for slash commands. This is a pretty standard autocomplete and
10641069
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.
10661071
10671072
This is meant to be passed into the :attr:`discord.Option.autocomplete` attribute.
10681073
1074+
Note
1075+
-----
1076+
Autocomplete cannot be used for options that have specified choices.
1077+
10691078
Example
10701079
--------
10711080
@@ -1075,8 +1084,8 @@ def basic_autocomplete(values: Union[Iterable[str],
10751084
10761085
# or
10771086
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
10801089
10811090
Option(str, "name", autocomplete=basic_autocomplete(autocomplete))
10821091
@@ -1085,22 +1094,24 @@ async def autocomplete(interaction):
10851094
10861095
Parameters
10871096
-----------
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`]]]]
10891098
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`.
10911100
10921101
Returns
10931102
--------
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`]]]]
10951104
A wrapped callback for the autocomplete.
10961105
"""
1097-
async def autocomplete_callback(ctx: AutocompleteContext) -> List[str]:
1106+
async def autocomplete_callback(ctx: AutocompleteContext) -> V:
10981107
_values = values # since we reassign later, python considers it local if we don't do this
10991108

11001109
if callable(_values):
1101-
_values = _values(interaction)
1110+
_values = _values(ctx)
11021111
if asyncio.iscoroutine(_values):
11031112
_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))
11051116

11061117
return autocomplete_callback

0 commit comments

Comments
 (0)