Make DEFAULT_CONTROLS and ReactionPredicate.*_EMOJIS immutable (#5666)

* Make ReactionPredicate.*_EMOJIS immutable

* Make menus.DEFAULT_CONTROLS immutable

* Actually convert NUMBER_EMOJIS to tuple
This commit is contained in:
jack1142 2022-04-09 21:35:11 +02:00 committed by GitHub
parent 6cb2378e2e
commit 96e8d8cdf5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 31 additions and 23 deletions

View File

@ -5,23 +5,28 @@
import asyncio
import contextlib
import functools
from typing import Iterable, List, Union
from types import MappingProxyType
from typing import Callable, Iterable, List, Mapping, TypeVar, Union
import discord
from .. import commands
from .predicates import ReactionPredicate
_T = TypeVar("_T")
_PageList = TypeVar("_PageList", List[str], List[discord.Embed])
_ReactableEmoji = Union[str, discord.Emoji]
_ControlCallable = Callable[[commands.Context, _PageList, discord.Message, int, float, str], _T]
async def menu(
ctx: commands.Context,
pages: Union[List[str], List[discord.Embed]],
controls: dict,
pages: _PageList,
controls: Mapping[str, _ControlCallable],
message: discord.Message = None,
page: int = 0,
timeout: float = 30.0,
):
) -> _T:
"""
An emoji-based menu
@ -40,9 +45,10 @@ async def menu(
The command context
pages: `list` of `str` or `discord.Embed`
The pages of the menu.
controls: dict
controls: Mapping[str, Callable],
A mapping of emoji to the function which handles the action for the
emoji.
emoji. The signature of the function should be the same as of this function
and should additionally accept an ``emoji`` parameter of type `str`.
message: discord.Message
The message representing the menu. Usually :code:`None` when first opening
the menu
@ -132,12 +138,12 @@ async def menu(
async def next_page(
ctx: commands.Context,
pages: list,
controls: dict,
controls: Mapping[str, _ControlCallable],
message: discord.Message,
page: int,
timeout: float,
emoji: str,
):
) -> _T:
if page == len(pages) - 1:
page = 0 # Loop around to the first item
else:
@ -148,12 +154,12 @@ async def next_page(
async def prev_page(
ctx: commands.Context,
pages: list,
controls: dict,
controls: Mapping[str, _ControlCallable],
message: discord.Message,
page: int,
timeout: float,
emoji: str,
):
) -> _T:
if page == 0:
page = len(pages) - 1 # Loop around to the last item
else:
@ -164,12 +170,12 @@ async def prev_page(
async def close_menu(
ctx: commands.Context,
pages: list,
controls: dict,
controls: Mapping[str, _ControlCallable],
message: discord.Message,
page: int,
timeout: float,
emoji: str,
):
) -> None:
with contextlib.suppress(discord.NotFound):
await message.delete()
@ -210,8 +216,10 @@ def start_adding_reactions(
return asyncio.create_task(task())
DEFAULT_CONTROLS = {
"\N{LEFTWARDS BLACK ARROW}\N{VARIATION SELECTOR-16}": prev_page,
"\N{CROSS MARK}": close_menu,
"\N{BLACK RIGHTWARDS ARROW}\N{VARIATION SELECTOR-16}": next_page,
}
DEFAULT_CONTROLS: Mapping[str, _ControlCallable] = MappingProxyType(
{
"\N{LEFTWARDS BLACK ARROW}\N{VARIATION SELECTOR-16}": prev_page,
"\N{CROSS MARK}": close_menu,
"\N{BLACK RIGHTWARDS ARROW}\N{VARIATION SELECTOR-16}": next_page,
}
)

View File

@ -881,19 +881,19 @@ class ReactionPredicate(Callable[[discord.Reaction, discord.abc.User], bool]):
)
"""Tuple[str, str] : A tuple containing the tick emoji and cross emoji, in that order."""
ALPHABET_EMOJIS: ClassVar[List[str]] = [
ALPHABET_EMOJIS: ClassVar[Tuple[str, ...]] = tuple(
chr(code)
for code in range(
ord("\N{REGIONAL INDICATOR SYMBOL LETTER A}"),
ord("\N{REGIONAL INDICATOR SYMBOL LETTER Z}") + 1,
)
]
"""List[str] : A list of all 26 alphabetical letter emojis."""
)
"""Tuple[str, ...] : A tuple of all 26 alphabetical letter emojis."""
NUMBER_EMOJIS: ClassVar[List[str]] = [
NUMBER_EMOJIS: ClassVar[Tuple[str, ...]] = tuple(
chr(code) + "\N{COMBINING ENCLOSING KEYCAP}" for code in range(ord("0"), ord("9") + 1)
]
"""List[str] : A list of all single-digit number emojis, 0 through 9."""
)
"""Tuple[str, ...] : A tuple of all single-digit number emojis, 0 through 9."""
def __init__(
self, predicate: Callable[["ReactionPredicate", discord.Reaction, discord.abc.User], bool]