mirror of
https://github.com/Rapptz/discord.py.git
synced 2025-04-22 08:44:10 +00:00
parent
87edabc5b8
commit
d1039e209e
@ -613,32 +613,34 @@ def get_supported_annotation(
|
||||
*,
|
||||
_none: type = NoneType,
|
||||
_mapping: Dict[Any, Type[Transformer]] = BUILT_IN_TRANSFORMERS,
|
||||
) -> Tuple[Any, Any]:
|
||||
) -> Tuple[Any, Any, bool]:
|
||||
"""Returns an appropriate, yet supported, annotation along with an optional default value.
|
||||
|
||||
The third boolean element of the tuple indicates if default values should be validated.
|
||||
|
||||
This differs from the built in mapping by supporting a few more things.
|
||||
Likewise, this returns a "transformed" annotation that is ready to use with CommandParameter.transform.
|
||||
"""
|
||||
|
||||
try:
|
||||
return (_mapping[annotation], MISSING)
|
||||
return (_mapping[annotation], MISSING, True)
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
if hasattr(annotation, '__discord_app_commands_transform__'):
|
||||
return (annotation.metadata, MISSING)
|
||||
return (annotation.metadata, MISSING, False)
|
||||
|
||||
if hasattr(annotation, '__metadata__'):
|
||||
return get_supported_annotation(annotation.__metadata__[0])
|
||||
|
||||
if inspect.isclass(annotation):
|
||||
if issubclass(annotation, Transformer):
|
||||
return (annotation, MISSING)
|
||||
return (annotation, MISSING, False)
|
||||
if issubclass(annotation, (Enum, InternalEnum)):
|
||||
if all(isinstance(v.value, (str, int, float)) for v in annotation):
|
||||
return (_make_enum_transformer(annotation), MISSING)
|
||||
return (_make_enum_transformer(annotation), MISSING, False)
|
||||
else:
|
||||
return (_make_complex_enum_transformer(annotation), MISSING)
|
||||
return (_make_complex_enum_transformer(annotation), MISSING, False)
|
||||
if annotation is Choice:
|
||||
raise TypeError(f'Choice requires a type argument of int, str, or float')
|
||||
|
||||
@ -646,11 +648,11 @@ def get_supported_annotation(
|
||||
origin = getattr(annotation, '__origin__', None)
|
||||
if origin is Literal:
|
||||
args = annotation.__args__ # type: ignore
|
||||
return (_make_literal_transformer(args), MISSING)
|
||||
return (_make_literal_transformer(args), MISSING, True)
|
||||
|
||||
if origin is Choice:
|
||||
arg = annotation.__args__[0] # type: ignore
|
||||
return (_make_choice_transformer(arg), MISSING)
|
||||
return (_make_choice_transformer(arg), MISSING, True)
|
||||
|
||||
if origin is not Union:
|
||||
# Only Union/Optional is supported right now so bail early
|
||||
@ -661,10 +663,10 @@ def get_supported_annotation(
|
||||
if args[-1] is _none:
|
||||
if len(args) == 2:
|
||||
underlying = args[0]
|
||||
inner, _ = get_supported_annotation(underlying)
|
||||
inner, _, validate_default = get_supported_annotation(underlying)
|
||||
if inner is None:
|
||||
raise TypeError(f'unsupported inner optional type {underlying!r}')
|
||||
return (inner, None)
|
||||
return (inner, None, validate_default)
|
||||
else:
|
||||
args = args[:-1]
|
||||
default = None
|
||||
@ -672,7 +674,7 @@ def get_supported_annotation(
|
||||
# Check for channel union types
|
||||
if any(arg in CHANNEL_TO_TYPES for arg in args):
|
||||
# If any channel type is given, then *all* must be channel types
|
||||
return (channel_transformer(*args, raw=None), default)
|
||||
return (channel_transformer(*args, raw=None), default, True)
|
||||
|
||||
# The only valid transformations here are:
|
||||
# [Member, User] => user
|
||||
@ -682,9 +684,9 @@ def get_supported_annotation(
|
||||
if not all(arg in supported_types for arg in args):
|
||||
raise TypeError(f'unsupported types given inside {annotation!r}')
|
||||
if args == (User, Member) or args == (Member, User):
|
||||
return (passthrough_transformer(AppCommandOptionType.user), default)
|
||||
return (passthrough_transformer(AppCommandOptionType.user), default, True)
|
||||
|
||||
return (passthrough_transformer(AppCommandOptionType.mentionable), default)
|
||||
return (passthrough_transformer(AppCommandOptionType.mentionable), default, True)
|
||||
|
||||
|
||||
def annotation_to_parameter(annotation: Any, parameter: inspect.Parameter) -> CommandParameter:
|
||||
@ -695,7 +697,7 @@ def annotation_to_parameter(annotation: Any, parameter: inspect.Parameter) -> Co
|
||||
of a command parameter.
|
||||
"""
|
||||
|
||||
(inner, default) = get_supported_annotation(annotation)
|
||||
(inner, default, validate_default) = get_supported_annotation(annotation)
|
||||
type = inner.type()
|
||||
|
||||
if default is MISSING or default is None:
|
||||
@ -704,12 +706,10 @@ def annotation_to_parameter(annotation: Any, parameter: inspect.Parameter) -> Co
|
||||
default = param_default
|
||||
|
||||
# Verify validity of the default parameter
|
||||
if default is not MISSING:
|
||||
enum_type = getattr(inner, '__discord_app_commands_transformer_enum__', None)
|
||||
if default.__class__ is not enum_type:
|
||||
valid_types: Tuple[Any, ...] = ALLOWED_DEFAULTS.get(type, (NoneType,))
|
||||
if not isinstance(default, valid_types):
|
||||
raise TypeError(f'invalid default parameter type given ({default.__class__}), expected {valid_types}')
|
||||
if default is not MISSING and validate_default:
|
||||
valid_types: Tuple[Any, ...] = ALLOWED_DEFAULTS.get(type, (NoneType,))
|
||||
if not isinstance(default, valid_types):
|
||||
raise TypeError(f'invalid default parameter type given ({default.__class__}), expected {valid_types}')
|
||||
|
||||
result = CommandParameter(
|
||||
type=type,
|
||||
|
Loading…
x
Reference in New Issue
Block a user