[commands] Add support for FlagConverter in hybrid commands

This works by unpacking and repacking the flag arguments in a flag.
If an unsupported type annotation is found then it will error at
definition time.
This commit is contained in:
Rapptz
2022-05-11 03:15:49 -04:00
parent 1607b6978b
commit 15ceca1e63
3 changed files with 198 additions and 40 deletions

View File

@ -28,7 +28,7 @@ import inspect
import re
import sys
from dataclasses import dataclass, field
from typing import TYPE_CHECKING, Any, Dict, Iterator, List, Literal, Optional, Pattern, Set, Tuple, Union
from typing import TYPE_CHECKING, Any, Dict, Iterator, List, Literal, Optional, Pattern, Set, Tuple, Type, Union
from discord.utils import MISSING, maybe_coroutine, resolve_annotation
@ -44,7 +44,7 @@ __all__ = (
if TYPE_CHECKING:
from typing_extensions import Self
from typing_extensions import Self, TypeGuard
from ._types import BotT
from .context import Context
@ -76,6 +76,9 @@ class Flag:
A negative value indicates an unlimited amount of arguments.
override: :class:`bool`
Whether multiple given values overrides the previous value.
description: :class:`str`
The description of the flag. Shown for hybrid commands when they're
used as application commands.
"""
name: str = MISSING
@ -85,6 +88,7 @@ class Flag:
default: Any = MISSING
max_args: int = MISSING
override: bool = MISSING
description: str = MISSING
cast_to_dict: bool = False
@property
@ -104,6 +108,7 @@ def flag(
max_args: int = MISSING,
override: bool = MISSING,
converter: Any = MISSING,
description: str = MISSING,
) -> Any:
"""Override default functionality and parameters of the underlying :class:`FlagConverter`
class attributes.
@ -128,8 +133,23 @@ def flag(
converter: Any
The converter to use for this flag. This replaces the annotation at
runtime which is transparent to type checkers.
description: :class:`str`
The description of the flag. Shown for hybrid commands when they're
used as application commands.
"""
return Flag(name=name, aliases=aliases, default=default, max_args=max_args, override=override, annotation=converter)
return Flag(
name=name,
aliases=aliases,
default=default,
max_args=max_args,
override=override,
annotation=converter,
description=description,
)
def is_flag(obj: Any) -> TypeGuard[Type[FlagConverter]]:
return hasattr(obj, '__commands_is_flag__')
def validate_flag_name(name: str, forbidden: Set[str]) -> None: