Skip to content

tanchan.doc_parse#

tanjun.annotations extension which uses docstring parsing.

SlashCommandGroup #

Bases: SlashCommandGroup

Extended implementation of tanjun.SlashCommandGroup with some doc parsing.

as_sub_command #

as_sub_command(name=None, description=None, *, always_defer=False, default_to_ephemeral=None, sort_options=True, validate_arg_keys=True)

Build a tanjun.SlashCommand in this command group by decorating a function.

Note

If you want your first response to be ephemeral while using always_defer, you must set default_to_ephemeral to True.

Parameters:

  • name (str | Mapping[str, str] | None, default: None ) –

    The command's name (supports localisation).

    If left as None then the command callback's name will be used.

    This must fit discord's requirements.

  • description (str | Mapping[str, str] | None, default: None ) –

    The command's description.

    If left as None then the first line of the command callback's description will be used.

    This should be inclusively between 1-100 characters in length.

  • always_defer (bool, default: False ) –

    Whether the contexts this command is executed with should always be deferred before being passed to the command's callback.

  • default_to_ephemeral (bool | None, default: None ) –

    Whether this command's responses should default to ephemeral unless flags are set to override this.

    If this is left as None then the default set on the parent command(s), component or client will be in effect.

  • sort_options (bool, default: True ) –

    Whether this command should sort its set options based on whether they're required.

    If this is True then the options are re-sorted to meet the requirement from Discord that required command options be listed before optional ones.

  • validate_arg_keys (bool, default: True ) –

    Whether to validate that option keys match the command callback's signature.

Returns:

Raises:

  • ValueError

    Raises a value error for any of the following reasons:

    • If the command name doesn't fit Discord's requirements.
    • If the command name has uppercase characters.
    • If the description is over 100 characters long.

make_sub_group #

make_sub_group(name, description, /, *, default_to_ephemeral=None)

Create a sub-command group in this group.

Note

Unlike message command groups, slash command groups cannot be callable functions themselves.

Parameters:

  • name (str | Mapping[str, str]) –

    The name of the command group (supports localisation).

    This must fit discord's requirements.

  • description (str | Mapping[str, str]) –

    The description of the command group.

  • default_to_ephemeral (bool | None, default: None ) –

    Whether this command's responses should default to ephemeral unless flags are set to override this.

    If this is left as None then the default set on the parent command(s), component or client will be in effect.

Returns:

Raises:

  • ValueError

    Raises a value error for any of the following reasons:

    • If the command name doesn't fit Discord's requirements.
    • If the command name has uppercase characters.
    • If the description is over 100 characters long.

as_slash_command #

as_slash_command(*, always_defer=False, default_member_permissions=None, default_to_ephemeral=None, description=None, dm_enabled=None, is_global=True, name=None, nsfw=False, sort_options=True, validate_arg_keys=True)

Build a tanjun.SlashCommand by decorating a function.

This uses the function's name as the command's name and the first line of its docstring as the command's description.

Note

Under the standard implementation, is_global is used to determine whether the command should be bulk set by Client.declare_global_commands or when declare_global_commands is True

Warning

default_member_permissions, dm_enabled and is_global are ignored for commands within slash command groups.

Note

If you want your first response to be ephemeral while using always_defer, you must set default_to_ephemeral to True.

Examples:

@doc_parse.as_slash_command()  # This command will be called "ping"
async def ping(ctx: tanjun.abc.SlashContext) -> None:
    """Get the bot's latency."""
    start_time = time.perf_counter()
    await ctx.rest.fetch_my_user()
    time_taken = (time.perf_counter() - start_time) * 1_000
    await ctx.respond(f"PONG\n - REST: {time_taken:.0f}mss")

Parameters:

  • always_defer (bool, default: False ) –

    Whether the contexts this command is executed with should always be deferred before being passed to the command's callback.

  • default_member_permissions (Permissions | int | None, default: None ) –

    Member permissions necessary to utilize this command by default.

    If this is None then the configuration for the parent component or client will be used.

  • default_to_ephemeral (bool | None, default: None ) –

    Whether this command's responses should default to ephemeral unless flags are set to override this.

    If this is left as None then the default set on the parent command(s), component or client will be in effect.

  • dm_enabled (bool | None, default: None ) –

    Whether this command is enabled in DMs with the bot.

    If this is None then the configuration for the parent component or client will be used.

  • is_global (bool, default: True ) –

    Whether this command is a global command.

  • name (str | Mapping[str, str] | None, default: None ) –

    The command's name.

    This must fit discord's requirements and if left as None then the command callback's name is used.

  • nsfw (bool, default: False ) –

    Whether this command should only be accessible in channels marked as nsfw.

  • sort_options (bool, default: True ) –

    Whether this command should sort its set options based on whether they're required.

    If this is True then the options are re-sorted to meet the requirement from Discord that required command options be listed before optional ones.

  • validate_arg_keys (bool, default: True ) –

    Whether to validate that option keys match the command callback's signature.

Returns:

Raises:

  • ValueError

    Raises a value error for any of the following reasons:

    • If the command name is over 32 characters long.
    • If the command name has uppercase characters.
    • If the description is over 100 characters long.

slash_command_group #

slash_command_group(name, description, /, *, default_member_permissions=None, default_to_ephemeral=None, dm_enabled=None, is_global=True, nsfw=False)

Create a slash command group.

Note

Unlike message command groups, slash command groups cannot be callable functions themselves.

Warning

default_member_permissions, dm_enabled and is_global are ignored for command groups within other slash command groups.

Note

Under the standard implementation, is_global is used to determine whether the command should be bulk set by Client.declare_global_commands or when declare_global_commands is True

Examples:

Sub-commands can be added to the created slash command object through the following decorator based approach:

help_group = doc_parse.slash_command_group("help", "get help")

@tanjun.with_str_slash_option("command_name", "command name")
@help_group.as_sub_command()
async def help(ctx: tanjun.abc.SlashContext, command_name: annotations.Str) -> None:
    """Get help with a command."""

@help_group.as_sub_command()
async def me(ctx: tanjun.abc.SlashContext) -> None:
    """Help me."""

component = tanjun.Component().add_slash_command(help_group)

Parameters:

  • name (str | Mapping[str, str]) –

    The name of the command group (supports localisation).

    This must fit discord's requirements.

  • description (str | Mapping[str, str]) –

    The description of the command group (supports localisation).

    This should be inclusively between 1-100 characters in length.

  • default_member_permissions (Permissions | int | None, default: None ) –

    Member permissions necessary to utilize this command by default.

    If this is None then the configuration for the parent component or client will be used.

  • default_to_ephemeral (bool | None, default: None ) –

    Whether this command's responses should default to ephemeral unless flags are set to override this.

    If this is left as None then the default set on the parent command(s), component or client will be in effect.

  • dm_enabled (bool | None, default: None ) –

    Whether this command is enabled in DMs with the bot.

    If this is None then the configuration for the parent component or client will be used.

  • is_global (bool, default: True ) –

    Whether this command is a global command.

  • nsfw (bool, default: False ) –

    Whether this command should only be accessible in channels marked as nsfw.

Returns:

Raises:

  • ValueError

    Raises a value error for any of the following reasons:

    • If the command name doesn't fit Discord's requirements.
    • If the command name has uppercase characters.
    • If the description is over 100 characters long.

with_annotated_args #

with_annotated_args(command: _CommandUnionT) -> _CommandUnionT
with_annotated_args(*, doc_style: _DocStyleUnion | None = None, follow_wrapped: bool = False) -> collections.Callable[[_CommandUnionT], _CommandUnionT]
with_annotated_args(command=None, /, *, doc_style=None, follow_wrapped=False)

Docstring parsing implementation of tanjun.annotations.with_annotated_args.

Examples:

This will parse command option descriptions from the command's docstring.

@doc_parse.with_annotated_args
@doc_parse.as_slash_command()
async def toggle_setting(ctx: tanjun.abc.Context, user: annotations.User, state: annotations.Bool = False) -> None:
    """Toggle this setting for a user.

    Parameters
    ----------
    user
        The user to toggle this setting for.
    state
        Whether this should be enabled.
    """

@doc_parse.with_annotated_args
@doc_parse.as_slash_command()
async def ban_user(ctx: tanjun.abc.Context, user: annotations.User) -> None:
    """Ban a user from this guild.

    Args:
        user:
            The user to ban.
    """

@doc_parse.with_annotated_args
@doc_parse.as_slash_command()
async def unban_user(
    ctx: tanjun.abc.Context, user: annotations.User, reason: annotations.Str | None = None
) -> None:
    """Unban a user from this guild.

    :param user: The user to unban.
    :param reason: The reason for unbanning them.
    """

This also supports parsing option descriptions from the typed dict that's being used as the unpacked **kwargs type-hint.

class BulkMessagOptions(typing.TypedDict, total=False):
    """Reused bulk message command options.

    Parameters
    ----------
    count
        The amount of messages to target.
    regex
        A regular expression to match against message contents.
    """

    count: annotations.Int
    regex: annotations.Str

@doc_parse.with_annotated_args
@doc_parse.as_slash_command()
async def delete_messages(
    ctx: tanjun.abc.Context, reason: annotations.Str | None = None, **kwargs: typing.Unpack[BulkMessagOptions]
) -> None:
    """Toggle this setting for a user.

    Parameters
    ----------
    reason
        Why you're bulk deleting these messages.
    """

Parameters:

  • command (SlashCommand | MessageCommand, default: None ) –

    The message or slash command to set the arguments for.

  • doc_style (_DocStyleUnion | None, default: None ) –

    The docstyle to parse slash command option descriptions from.

    This may be either "google", "numpy", or "reST". If left as None then this will try to auto-detect the style.

  • follow_wrapped (bool, default: False ) –

    Whether this should also set the arguments on any other command objects this wraps in a decorator call chain.

Returns:

Raises:

  • RuntimeError

    If doc_style is None and this failed to detect the docstring style.