Rapptz / discord.py

An API wrapper for Discord written in Python.
http://discordpy.rtfd.org/en/latest
MIT License
14.7k stars 3.74k forks source link

How to check if parameter in command function is str, int or float #1924

Closed d4sein closed 5 years ago

d4sein commented 5 years ago
async def clear(ctx, amount=100):
    if isinstance(amount, str):

I want to check if amount is a str or float, but it errors out before it can do anything:

raise BadArgument('Converting to "{0.name}" failed.'.format(converter)) from e discord.ext.commands.errors.BadArgument: Converting to "int"

d4sein commented 5 years ago

It gives me this error if I try to pass a str as an argument

Gorialis commented 5 years ago

Commands intentionally do strict typing to ensure your code behaves consistently. In this case, your default is an int, so the library will always cast to an int and will raise a UserInputError if it gets something that isn't an int.

It is good practice to explicitly type hint what you need:

async def example_command(ctx, argument: int):
    ...

Note that without any hinting, the default type for arguments is str. With hinting, you will not receive anything other than the type specified.

On the rewrite branch, it is possible to use a typing.Union to specify fallbacks if conversions fail, at which point you could use isinstance as normal:

async def example_command(ctx, argument: typing.Union[int, float, str]):
    if isinstance(argument, int):
        ...  # do something
    elif isinstance(argument, float):
        ...  # do something else
    else:
        ...  # this is the str branch

Otherwise, you could write a custom Converter, or accept a str and convert it yourself.

Harmon758 commented 5 years ago

The documentation for the typing.Union converter on the rewrite branch: https://discordpy.readthedocs.io/en/rewrite/ext/commands/commands.html#typing-union

For further help, you should join either the official discord.py server or the Discord API server, as the README recommends.