Skip to content

Passing choices= to an option and typing it as Literal fails #3091

@ToothyDev

Description

@ToothyDev

Summary

Passing choices= to an option and typing it as Literal fails WHEN not passing input_type

Reproduction Steps

Add the command below as-is to your bot, and run it

Minimal Reproducible Code

@slash_command()
@option(
        "test",
        choices=["jpeg", "png", "gif", "webp", "tiff", "bmp"],
    )
    async def convert(
        self,
        ctx: discord.ApplicationContext,
        test: Literal["jpeg", "png", "gif", "webp", "tiff", "bmp"],
    ) -> None:
    ...

Expected Results

The option decorator should ignore the typing in the code when using the decorator, so it doesn't matter what it's typed as

Actual Results

The option decorator is confused by the Literal[] typing and fails to decide on what to do, seemingly

Intents

all

System Information

- Python v3.13.11-final
- py-cord v2.7.None-final
- aiohttp v3.13.3
- system info: Windows 11 10.0.26200

Checklist

  • I have searched the open issues for duplicates.
  • I have shown the entire traceback, if possible.
  • I have removed my token from display, if visible.

Additional Context

Traceback:

Traceback (most recent call last):
  File "C:\Code\versa\.venv\Lib\site-packages\discord\cog.py", line 809, in _load_from_module_spec
    spec.loader.exec_module(lib)  # type: ignore
    ~~~~~~~~~~~~~~~~~~~~~~~^^^^^
  File "<frozen importlib._bootstrap_external>", line 1023, in exec_module
  File "<frozen importlib._bootstrap>", line 488, in _call_with_frames_removed
  File "C:\Code\versa\src\cogs\slash_commands.py", line 13, in <module>
    class SlashCommands(discord.Cog, name="slash_commands"):
    ...<72 lines>...
            return buffer
  File "C:\Code\versa\src\cogs\slash_commands.py", line 19, in SlashCommands
    @option(
     ~~~~~~^
        "target_filetype",
        ^^^^^^^^^^^^^^^^^^
        description="The filetype to convert to",
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        choices=["jpeg", "png", "gif", "webp", "tiff", "bmp"],
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    )
    ^
  File "C:\Code\versa\.venv\Lib\site-packages\discord\commands\options.py", line 553, in decorator
    func.__annotations__[resolved_name] = Option(itype, name=name, **kwargs)
                                          ~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Code\versa\.venv\Lib\site-packages\discord\commands\options.py", line 287, in __init__
    raise exc
  File "C:\Code\versa\.venv\Lib\site-packages\discord\commands\options.py", line 282, in __init__
    self.input_type = SlashCommandOptionType.from_datatype(input_type)
                      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^
  File "C:\Code\versa\.venv\Lib\site-packages\discord\enums.py", line 863, in from_datatype
    if isinstance(datatype, str) or issubclass(datatype, str):
                                    ~~~~~~~~~~^^^^^^^^^^^^^^^
TypeError: issubclass() arg 1 must be a class

An important note is that when explicitly passing input_type to the option (in this case, str), the given code works. input_type defaults to string by default. I think the solution is to have input_type always fall back to string unless another Discord-compatible option type is present as the function argument type, e.g. int / float.

Metadata

Metadata

Assignees

No one assigned

    Labels

    unconfirmed bugA bug report that needs triaging

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions