From a295b4ab38b4e0e19165d95245e7b80bf9c2857a Mon Sep 17 00:00:00 2001 From: Gnome Date: Tue, 21 Sep 2021 20:49:09 +0100 Subject: [PATCH 1/9] Fix command checks actually working --- discord/ext/commands/core.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/discord/ext/commands/core.py b/discord/ext/commands/core.py index 5947dc19..5d48eb8f 100644 --- a/discord/ext/commands/core.py +++ b/discord/ext/commands/core.py @@ -399,9 +399,9 @@ class Command(_BaseCommand, Generic[CogT, P, T]): command_attrs = {} try: - checks = command_attrs.pop("checks") + checks = func.__commands_checks__ checks.reverse() - except KeyError: + except AttributeError: checks = kwargs.get("checks", []) try: -- 2.47.2 From 02c6b078340541023bc23c15a76f29bfd2363666 Mon Sep 17 00:00:00 2001 From: Gnome! <45660393+Gnome-py@users.noreply.github.com> Date: Tue, 21 Sep 2021 22:34:54 +0100 Subject: [PATCH 2/9] Merge pull request #72 * Fix command checks actually working --- discord/ext/commands/core.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/discord/ext/commands/core.py b/discord/ext/commands/core.py index 5947dc19..5d48eb8f 100644 --- a/discord/ext/commands/core.py +++ b/discord/ext/commands/core.py @@ -399,9 +399,9 @@ class Command(_BaseCommand, Generic[CogT, P, T]): command_attrs = {} try: - checks = command_attrs.pop("checks") + checks = func.__commands_checks__ checks.reverse() - except KeyError: + except AttributeError: checks = kwargs.get("checks", []) try: -- 2.47.2 From 0637a628caa8734a6a12156ab7a340ddd0e63576 Mon Sep 17 00:00:00 2001 From: Tom <47765953+IAmTomahawkx@users.noreply.github.com> Date: Tue, 21 Sep 2021 14:51:46 -0700 Subject: [PATCH 3/9] update workflows (#73) * modify workflows to fit into one file, fix pyright workflow * remove redundant pip install * add check flag to black * use psf/black for black checker --- .github/workflows/black.yml | 25 ------------------------- .github/workflows/ci.yml | 16 ++++++++++++++-- 2 files changed, 14 insertions(+), 27 deletions(-) delete mode 100644 .github/workflows/black.yml diff --git a/.github/workflows/black.yml b/.github/workflows/black.yml deleted file mode 100644 index b95fb1dd..00000000 --- a/.github/workflows/black.yml +++ /dev/null @@ -1,25 +0,0 @@ -name: Lint - -on: [push] - -jobs: - lint: - runs-on: ubuntu-latest - steps: - - name: checkout - uses: actions/checkout@v2 - - - name: Setup Python - uses: actions/setup-python@v1 - with: - python-version: 3.8 - - - name: install black - run: pip install black - - - name: run linter - uses: wearerequired/lint-action@v1 - with: - black: true - black_args: ". --line-length 120" - auto_fix: true \ No newline at end of file diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f4dd5c56..27a7e1d0 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -3,7 +3,7 @@ name: CI on: [push, pull_request] jobs: - lint: + pyright: runs-on: ubuntu-latest steps: - name: checkout @@ -22,5 +22,17 @@ jobs: - name: Run type checking run: | npm install -g pyright - pip install -r requirements.txt + pip install . pyright --lib --verifytypes discord --ignoreexternal + + black: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v2 + + - name: Run linter + uses: psf/black@stable + with: + options: "--line-length 120 --check" + src: "./discord" \ No newline at end of file -- 2.47.2 From b9a24b7c389428dae8b944228f2ebeea3be5264a Mon Sep 17 00:00:00 2001 From: Gnome Date: Fri, 24 Sep 2021 20:57:49 +0100 Subject: [PATCH 4/9] Current progress on slash command docs --- discord/ext/commands/converter.py | 55 +++++++++---- discord/ext/commands/core.py | 9 ++- docs/ext/commands/api.rst | 6 ++ docs/ext/commands/commands.rst | 113 +++++++++++++++------------ docs/ext/commands/index.rst | 1 + docs/ext/commands/slash-commands.rst | 21 +++++ 6 files changed, 139 insertions(+), 66 deletions(-) create mode 100644 docs/ext/commands/slash-commands.rst diff --git a/discord/ext/commands/converter.py b/discord/ext/commands/converter.py index 8504f4a0..feff650d 100644 --- a/discord/ext/commands/converter.py +++ b/discord/ext/commands/converter.py @@ -1008,27 +1008,50 @@ class Greedy(List[T]): return cls(converter=converter) -if TYPE_CHECKING: +class Option(Generic[T, DT]): # type: ignore + """A special 'converter' to apply a description to slash command options. + For example in the following code: + + .. code-block:: python3 + + @bot.command() + async def ban(ctx, + member: discord.Member, *, + reason: str = commands.Option('no reason', description='the reason to ban this member') + ): + await member.ban(reason=reason) + + The description would be ``the reason to ban this member`` and the default would be ``no reason`` + + .. versionadded:: 2.0 + + Attributes + ------------ + default: Optional[Any] + The default for this option, overwrites Option during parsing. + description: :class:`str` + The description for this option, is unpacked to :attr:`.Command.option_descriptions` + """ + + description: DT + default: Union[T, inspect._empty] + __slots__ = ( + "default", + "description", + ) + + def __init__(self, default: T = inspect.Parameter.empty, *, description: DT) -> None: + self.description = description + self.default = default + + +if TYPE_CHECKING: + # Terrible workaround for type checking reasons def Option(default: T = inspect.Parameter.empty, *, description: str) -> T: ... -else: - - class Option(Generic[T, DT]): - description: DT - default: Union[T, inspect.Parameter.empty] - __slots__ = ( - "default", - "description", - ) - - def __init__(self, default: T = inspect.Parameter.empty, *, description: DT) -> None: - self.description = description - self.default = default - - def _convert_to_bool(argument: str) -> bool: lowered = argument.lower() if lowered in ("yes", "y", "true", "t", "1", "enable", "on"): diff --git a/discord/ext/commands/core.py b/discord/ext/commands/core.py index 5d48eb8f..3f1f25d9 100644 --- a/discord/ext/commands/core.py +++ b/discord/ext/commands/core.py @@ -123,7 +123,7 @@ application_option_type_lookup = { discord.Member, discord.User, ): 6, # Preferably discord.abc.User, but 'Protocols with non-method members don't support issubclass()' - (discord.abc.GuildChannel, discord.DMChannel): 7, + (discord.abc.GuildChannel, discord.Thread): 7, discord.Role: 8, discord.Object: 9, float: 10, @@ -322,11 +322,16 @@ class Command(_BaseCommand, Generic[CogT, P, T]): This overwrites the global ``slash_commands`` parameter of :class:`.Bot`. .. versionadded:: 2.0 - slash_command_guilds: Optional[:class:`List[int]`] + slash_command_guilds: Optional[List[:class:`int`]] If this is set, only upload this slash command to these guild IDs. This overwrites the global ``slash_command_guilds`` parameter of :class:`.Bot`. + .. versionadded:: 2.0 + + option_descriptions: Dict[:class:`str`, :class:`str`] + The unpacked option descriptions from :class:`.Option`. + .. versionadded:: 2.0 """ __original_kwargs__: Dict[str, Any] diff --git a/docs/ext/commands/api.rst b/docs/ext/commands/api.rst index e9631514..f70d835c 100644 --- a/docs/ext/commands/api.rst +++ b/docs/ext/commands/api.rst @@ -429,6 +429,12 @@ Converters .. autofunction:: discord.ext.commands.run_converters +Option +~~~~~~ + +.. autoclass:: discord.ext.commands.Option + :members: + Flag Converter ~~~~~~~~~~~~~~~ diff --git a/docs/ext/commands/commands.rst b/docs/ext/commands/commands.rst index 0f73f050..f29dc70b 100644 --- a/docs/ext/commands/commands.rst +++ b/docs/ext/commands/commands.rst @@ -61,12 +61,6 @@ the name to something other than the function would be as simple as doing this: async def _list(ctx, arg): pass -Slash Commands --------------- -Slash Commands can be enabled in the :class:`.Bot` constructor or :class:`.Command` constructor, using -``slash_commands=True`` or ``slash_command=True`` respectfully. All features of the commands extension -should work with these options enabled, however many will not have direct discord counterparts and therefore -will be subsituted for supported versions when uploaded to discord. Parameters ------------ @@ -140,6 +134,11 @@ at all: Since the ``args`` variable is a :class:`py:tuple`, you can do anything you would usually do with one. +.. admonition:: Slash Command Only + + This functionally is currently not supported by the slash command API, so is turned into + a single ``STRING`` parameter on discord's end which we do our own parsing on. + Keyword-Only Arguments ++++++++++++++++++++++++ @@ -186,7 +185,8 @@ know how the command was executed. It contains a lot of useful information: The context implements the :class:`abc.Messageable` interface, so anything you can do on a :class:`abc.Messageable` you can do on the :class:`~ext.commands.Context`. -.. warning:: +.. admonition:: Slash Command Only + :attr:`.Context.message` will be fake if in a slash command, it is not recommended to access if :attr:`.Context.interaction` is not None as most methods will error due to the message not actually existing. @@ -412,47 +412,55 @@ specify. Under the hood, these are implemented by the :ref:`ext_commands_adv_converters` interface. A table of the equivalent converter is given below: -+--------------------------+-------------------------------------------------+ -| Discord Class | Converter | -+--------------------------+-------------------------------------------------+ -| :class:`Object` | :class:`~ext.commands.ObjectConverter` | -+--------------------------+-------------------------------------------------+ -| :class:`Member` | :class:`~ext.commands.MemberConverter` | -+--------------------------+-------------------------------------------------+ -| :class:`User` | :class:`~ext.commands.UserConverter` | -+--------------------------+-------------------------------------------------+ -| :class:`Message` | :class:`~ext.commands.MessageConverter` | -+--------------------------+-------------------------------------------------+ -| :class:`PartialMessage` | :class:`~ext.commands.PartialMessageConverter` | -+--------------------------+-------------------------------------------------+ -| :class:`.GuildChannel` | :class:`~ext.commands.GuildChannelConverter` | -+--------------------------+-------------------------------------------------+ -| :class:`TextChannel` | :class:`~ext.commands.TextChannelConverter` | -+--------------------------+-------------------------------------------------+ -| :class:`VoiceChannel` | :class:`~ext.commands.VoiceChannelConverter` | -+--------------------------+-------------------------------------------------+ -| :class:`StageChannel` | :class:`~ext.commands.StageChannelConverter` | -+--------------------------+-------------------------------------------------+ -| :class:`StoreChannel` | :class:`~ext.commands.StoreChannelConverter` | -+--------------------------+-------------------------------------------------+ -| :class:`CategoryChannel` | :class:`~ext.commands.CategoryChannelConverter` | -+--------------------------+-------------------------------------------------+ -| :class:`Invite` | :class:`~ext.commands.InviteConverter` | -+--------------------------+-------------------------------------------------+ -| :class:`Guild` | :class:`~ext.commands.GuildConverter` | -+--------------------------+-------------------------------------------------+ -| :class:`Role` | :class:`~ext.commands.RoleConverter` | -+--------------------------+-------------------------------------------------+ -| :class:`Game` | :class:`~ext.commands.GameConverter` | -+--------------------------+-------------------------------------------------+ -| :class:`Colour` | :class:`~ext.commands.ColourConverter` | -+--------------------------+-------------------------------------------------+ -| :class:`Emoji` | :class:`~ext.commands.EmojiConverter` | -+--------------------------+-------------------------------------------------+ -| :class:`PartialEmoji` | :class:`~ext.commands.PartialEmojiConverter` | -+--------------------------+-------------------------------------------------+ -| :class:`Thread` | :class:`~ext.commands.ThreadConverter` | -+--------------------------+-------------------------------------------------+ ++--------------------------+-------------------------------------------------+-----------------------------+ +| Discord Class | Converter | Supported By Slash Commands | ++--------------------------+-------------------------------------------------+-----------------------------+ +| :class:`Object` | :class:`~ext.commands.ObjectConverter` | Not currently | ++--------------------------+-------------------------------------------------+-----------------------------+ +| :class:`Member` | :class:`~ext.commands.MemberConverter` | Yes, as type 6 (USER) | ++--------------------------+-------------------------------------------------+-----------------------------+ +| :class:`User` | :class:`~ext.commands.UserConverter` | Yes, as type 6 (USER) | ++--------------------------+-------------------------------------------------+-----------------------------+ +| :class:`Message` | :class:`~ext.commands.MessageConverter` | Not currently | ++--------------------------+-------------------------------------------------+-----------------------------+ +| :class:`PartialMessage` | :class:`~ext.commands.PartialMessageConverter` | Not currently | ++--------------------------+-------------------------------------------------+-----------------------------+ +| :class:`.GuildChannel` | :class:`~ext.commands.GuildChannelConverter` | Yes, as type 7 (CHANNEL) | ++--------------------------+-------------------------------------------------+-----------------------------+ +| :class:`TextChannel` | :class:`~ext.commands.TextChannelConverter` | Yes, as type 7 (CHANNEL) | ++--------------------------+-------------------------------------------------+-----------------------------+ +| :class:`VoiceChannel` | :class:`~ext.commands.VoiceChannelConverter` | Yes, as type 7 (CHANNEL) | ++--------------------------+-------------------------------------------------+-----------------------------+ +| :class:`StageChannel` | :class:`~ext.commands.StageChannelConverter` | Yes, as type 7 (CHANNEL) | ++--------------------------+-------------------------------------------------+-----------------------------+ +| :class:`StoreChannel` | :class:`~ext.commands.StoreChannelConverter` | Yes, as type 7 (CHANNEL) | ++--------------------------+-------------------------------------------------+-----------------------------+ +| :class:`CategoryChannel` | :class:`~ext.commands.CategoryChannelConverter` | Yes, as type 7 (CHANNEL) | ++--------------------------+-------------------------------------------------+-----------------------------+ +| :class:`Thread` | :class:`~ext.commands.ThreadConverter` | Yes, as type 7 (CHANNEL) | ++--------------------------+-------------------------------------------------+-----------------------------+ +| :class:`Invite` | :class:`~ext.commands.InviteConverter` | Not currently | ++--------------------------+-------------------------------------------------+-----------------------------+ +| :class:`Guild` | :class:`~ext.commands.GuildConverter` | Not currently | ++--------------------------+-------------------------------------------------+-----------------------------+ +| :class:`Role` | :class:`~ext.commands.RoleConverter` | Yes, as type 8 (ROLE) | ++--------------------------+-------------------------------------------------+-----------------------------+ +| :class:`Game` | :class:`~ext.commands.GameConverter` | Not currently | ++--------------------------+-------------------------------------------------+-----------------------------+ +| :class:`Colour` | :class:`~ext.commands.ColourConverter` | Not currently | ++--------------------------+-------------------------------------------------+-----------------------------+ +| :class:`Emoji` | :class:`~ext.commands.EmojiConverter` | Not currently | ++--------------------------+-------------------------------------------------+-----------------------------+ +| :class:`PartialEmoji` | :class:`~ext.commands.PartialEmojiConverter` | Not currently | ++--------------------------+-------------------------------------------------+-----------------------------+ + +.. admonition:: Slash Command Only + + If a slash command is not marked on the table above as supported, it will be sent as type 3 (STRING) + and parsed by normal content parsing, see + `the discord documentation `_ + for all supported types by the API. + By providing the converter it allows us to use them as building blocks for another converter: @@ -499,6 +507,10 @@ then a special error is raised, :exc:`~ext.commands.BadUnionArgument`. Note that any valid converter discussed above can be passed in to the argument list of a :data:`typing.Union`. +.. admonition:: Slash Command Only + + These are not currently supported by the Discord API and will be sent as type 3 (STRING) + typing.Optional ^^^^^^^^^^^^^^^^^ @@ -692,6 +704,11 @@ In order to customise the flag syntax we also have a few options that can be pas a command line parser. The syntax is mainly inspired by Discord's search bar input and as a result all flags need a corresponding value. +.. admonition:: Slash Command Only + + As these are built very similar to slash command options, they are converted into options and parsed + back into flags when the slash command is executed. + The flag converter is similar to regular commands and allows you to use most types of converters (with the exception of :class:`~ext.commands.Greedy`) as the type annotation. Some extra support is added for specific annotations as described below. diff --git a/docs/ext/commands/index.rst b/docs/ext/commands/index.rst index fba57359..9fd5e63c 100644 --- a/docs/ext/commands/index.rst +++ b/docs/ext/commands/index.rst @@ -15,4 +15,5 @@ extension library that handles this for you. commands cogs extensions + slash-commands api diff --git a/docs/ext/commands/slash-commands.rst b/docs/ext/commands/slash-commands.rst new file mode 100644 index 00000000..a30e47e1 --- /dev/null +++ b/docs/ext/commands/slash-commands.rst @@ -0,0 +1,21 @@ +.. currentmodule:: discord + +.. _ext_commands_slash_commands: + +Slash Commands +============== + +Slash Commands are currently supported in enhanced-discord.py using a system on top of ext.commands. + +This system is very simple to use, and can be enabled via :attr:`.Bot.slash_commands` globally, +or only for specific commands via :attr:`.Command.slash_command`. + +There is also the parameter ``slash_command_guilds`` which can be passed to either :class:`.Bot` or the command decorator +in order to only upload the commands as guild commands to these specific guild IDs, however this should only be used for +testing or small (<10 guilds) bots. + +If you want to add option descriptions to your commands, you should use :class:`.Option` + +.. admonition:: Slash Command Only + + For parts of the docs specific to slash commands, look for this box! -- 2.47.2 From 8b0be066e14b83072cbb6248ee6d6467aa5f505b Mon Sep 17 00:00:00 2001 From: Gnome Date: Sat, 25 Sep 2021 18:36:19 +0100 Subject: [PATCH 5/9] Improve docs for slash commands further --- docs/ext/commands/slash-commands.rst | 8 ++++--- docs/faq.rst | 31 ++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 3 deletions(-) diff --git a/docs/ext/commands/slash-commands.rst b/docs/ext/commands/slash-commands.rst index a30e47e1..db0b89b6 100644 --- a/docs/ext/commands/slash-commands.rst +++ b/docs/ext/commands/slash-commands.rst @@ -10,12 +10,14 @@ Slash Commands are currently supported in enhanced-discord.py using a system on This system is very simple to use, and can be enabled via :attr:`.Bot.slash_commands` globally, or only for specific commands via :attr:`.Command.slash_command`. -There is also the parameter ``slash_command_guilds`` which can be passed to either :class:`.Bot` or the command decorator -in order to only upload the commands as guild commands to these specific guild IDs, however this should only be used for -testing or small (<10 guilds) bots. +There is also the parameter ``slash_command_guilds`` which can be passed to either :class:`.Bot` or the command +decorator in order to only upload the commands as guild commands to these specific guild IDs, however this +should only be used for testing or small (<10 guilds) bots. If you want to add option descriptions to your commands, you should use :class:`.Option` +For troubleshooting, see the :ref:`FAQ ` + .. admonition:: Slash Command Only For parts of the docs specific to slash commands, look for this box! diff --git a/docs/faq.rst b/docs/faq.rst index 3f46d2a9..556bb34f 100644 --- a/docs/faq.rst +++ b/docs/faq.rst @@ -410,3 +410,34 @@ Example: :: await ctx.send(f'Pushing to {remote} {branch}') This could then be used as ``?git push origin master``. + +How do I make slash commands? +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +See :doc:`/ext/commands/slash-commands` + +My slash commands aren't showing up! +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. _ext_commands_slash_command_troubleshooting: + +You need to invite your bot with the ``application.commands`` scope on each guild and +you need the :attr:`Permissions.use_slash_commands` permission in order to see slash commands. + +.. image:: /images/discord_oauth2_slash_scope.png + :alt: The scopes checkbox with "bot" and "applications.commands" ticked. + +Global slash commands (created by not specifying :attr:`~ext.commands.Bot.slash_command_guilds`) will also take up an +hour to refresh on discord's end, so it is recommended to set :attr:`~ext.commands.Bot.slash_command_guilds` for development. + +If none of this works, make sure you are actually running enhanced-discord.py by doing ``print(bot.slash_commands)`` + +My bot won't start after enabling slash commands! +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +This means some of your command metadata is invalid for slash commands. +Make sure your command names and option names are lowercase, and they have to match the regex ``^[\w-]{1,32}$`` + +If you cannot figure out the problem, you should disable slash commands globally (:attr:`~ext.commands.Bot.slash_commands`\=False) +then go through commands, enabling them specifically with :attr:`~.commands.Command.slash_command`\=True until it +errors, then you can debug the problem with that command specifically. -- 2.47.2 From 163d8e65863d45463c26c3572b6bf4500934d43b Mon Sep 17 00:00:00 2001 From: NORXND Date: Sun, 26 Sep 2021 07:39:09 +0200 Subject: [PATCH 6/9] Merge pull request #76 * Fix docs in BadInviteArgument class --- discord/ext/commands/errors.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/discord/ext/commands/errors.py b/discord/ext/commands/errors.py index 77aa4a8f..c8dde033 100644 --- a/discord/ext/commands/errors.py +++ b/discord/ext/commands/errors.py @@ -455,6 +455,11 @@ class BadInviteArgument(BadArgument): This inherits from :exc:`BadArgument` .. versionadded:: 1.5 + + Attributes + ----------- + argument: :class:`str` + The invite supplied by the caller that was not found """ def __init__(self, argument: str) -> None: -- 2.47.2 From 093a38527dd755d94a90c41f8ca32d2c3998e6a7 Mon Sep 17 00:00:00 2001 From: Gnome! <45660393+Gnome-py@users.noreply.github.com> Date: Sun, 26 Sep 2021 06:40:35 +0100 Subject: [PATCH 7/9] Fix slash command prefix to / (#75) --- discord/ext/commands/bot.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/discord/ext/commands/bot.py b/discord/ext/commands/bot.py index 7abd6c8a..b438b4fe 100644 --- a/discord/ext/commands/bot.py +++ b/discord/ext/commands/bot.py @@ -1065,6 +1065,9 @@ class BotBase(GroupMixin): A list of prefixes or a single prefix that the bot is listening for. """ + if isinstance(message, _FakeSlashMessage): + return "/" + prefix = ret = self.command_prefix if callable(prefix): ret = await discord.utils.maybe_coroutine(prefix, self, message) @@ -1261,15 +1264,12 @@ class BotBase(GroupMixin): else: return # cannot do anything without stable channel - # Fetch a valid prefix, so process_commands can function + # Make our fake message so we can pass it to ext.commands message: discord.Message = _FakeSlashMessage.from_interaction(interaction, channel) # type: ignore - prefix = await self.get_prefix(message) - if isinstance(prefix, list): - prefix = prefix[0] + message.content = f"/{command_name} " # Add arguments to fake message content, in the right order ignore_params: List[inspect.Parameter] = [] - message.content = f"{prefix}{command_name} " for name, param in command.clean_params.items(): if inspect.isclass(param.annotation) and issubclass(param.annotation, FlagConverter): for name, flag in param.annotation.get_flags().items(): -- 2.47.2 From 456d71d2283a01176a50d2de76833e24084217df Mon Sep 17 00:00:00 2001 From: Gnome! <45660393+Gnome-py@users.noreply.github.com> Date: Sun, 26 Sep 2021 06:41:43 +0100 Subject: [PATCH 8/9] Add better support for MENTIONABLE (#74) --- discord/ext/commands/core.py | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/discord/ext/commands/core.py b/discord/ext/commands/core.py index 5d48eb8f..97609ac0 100644 --- a/discord/ext/commands/core.py +++ b/discord/ext/commands/core.py @@ -54,7 +54,16 @@ import discord from .errors import * from .cooldowns import Cooldown, BucketType, CooldownMapping, MaxConcurrency, DynamicCooldownMapping -from .converter import CONVERTER_MAPPING, Converter, run_converters, get_converter, Greedy, Option +from .converter import ( + CONVERTER_MAPPING, + Converter, + MemberConverter, + RoleConverter, + run_converters, + get_converter, + Greedy, + Option, +) from ._types import _BaseCommand from .cog import Cog from .context import Context @@ -125,7 +134,6 @@ application_option_type_lookup = { ): 6, # Preferably discord.abc.User, but 'Protocols with non-method members don't support issubclass()' (discord.abc.GuildChannel, discord.DMChannel): 7, discord.Role: 8, - discord.Object: 9, float: 10, } @@ -1215,7 +1223,6 @@ class Command(_BaseCommand, Generic[CogT, P, T]): def _param_to_options( self, name: str, annotation: Any, required: bool, varadic: bool ) -> List[Optional[ApplicationCommandInteractionDataOption]]: - origin = getattr(annotation, "__origin__", None) if inspect.isclass(annotation) and issubclass(annotation, FlagConverter): return [ @@ -1235,6 +1242,7 @@ class Command(_BaseCommand, Generic[CogT, P, T]): annotation, origin = annotation.__args__[0], None option: Dict[str, Any] = { + "type": 3, "name": name, "required": required, "description": self.option_descriptions[name], @@ -1249,12 +1257,15 @@ class Command(_BaseCommand, Generic[CogT, P, T]): # one, in which we can get the original type, eg, (MemberConverter -> Member) annotation = REVERSED_CONVERTER_MAPPING.get(annotation, annotation) - option["type"] = 3 for python_type, discord_type in application_option_type_lookup.items(): if issubclass(annotation, python_type): option["type"] = discord_type break + elif origin is Union: + if annotation in {Union[discord.Member, discord.Role], Union[MemberConverter, RoleConverter]}: + option["type"] = 9 + elif origin is Literal: literal_values = annotation.__args__ python_type = type(literal_values[0]) @@ -1268,7 +1279,6 @@ class Command(_BaseCommand, Generic[CogT, P, T]): {"name": literal_value, "value": literal_value} for literal_value in annotation.__args__ ] - option.setdefault("type", 3) # STRING return [option] # type: ignore def to_application_command(self, nested: int = 0) -> Optional[EditApplicationCommand]: -- 2.47.2 From d16d2d856f71b6a10e5aaf60d7f46cf2cf6b309d Mon Sep 17 00:00:00 2001 From: Chiggy-Playz <49774426+Chiggy-Playz@users.noreply.github.com> Date: Sun, 26 Sep 2021 11:13:23 +0530 Subject: [PATCH 9/9] Sort subcommand names (#68) --- discord/ext/commands/core.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/discord/ext/commands/core.py b/discord/ext/commands/core.py index 97609ac0..b6fb6954 100644 --- a/discord/ext/commands/core.py +++ b/discord/ext/commands/core.py @@ -1689,7 +1689,7 @@ class Group(GroupMixin[CogT], Command[CogT, P, T]): "name": self.name, "type": int(not (nested - 1)) + 1, "description": self.short_doc or "no description", - "options": [cmd.to_application_command(nested=nested + 1) for cmd in self.commands], + "options": [cmd.to_application_command(nested=nested + 1) for cmd in sorted(self.commands, key=lambda x: x.name)], } -- 2.47.2