Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: attribute error in command serialization #2243

2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,8 @@ These changes are available on the `master` branch, but have not yet been releas
recognize them. ([#2256](https://github.com/Pycord-Development/pycord/pull/2256))
- Fixed offset-aware tasks causing `TypeError` when being prepared.
([#2271](https://github.com/Pycord-Development/pycord/pull/2271))
- Fixed `AttributeError` when serializing commands with `Annotated` type hints.
([#2243](https://github.com/Pycord-Development/pycord/pull/2243))

## [2.4.1] - 2023-03-20

Expand Down
6 changes: 4 additions & 2 deletions discord/commands/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -746,10 +746,12 @@ def _parse_options(self, params, *, check_params: bool = True) -> list[Option]:
option = next(option_gen, Option())
# Handle Optional
if self._is_typing_optional(type_hint):
option.input_type = get_args(type_hint)[0]
option.input_type = SlashCommandOptionType.from_datatype(
get_args(type_hint)[0]
)
option.default = None
else:
option.input_type = type_hint
option.input_type = SlashCommandOptionType.from_datatype(type_hint)

if self._is_typing_union(option):
if self._is_typing_optional(option):
Expand Down
46 changes: 42 additions & 4 deletions tests/test_typing_annotated.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
from typing import Optional

import pytest
from typing_extensions import Annotated

import discord
from discord import ApplicationContext
from discord import SlashCommandOptionType
from discord.commands.core import SlashCommand, slash_command


Expand All @@ -15,6 +14,10 @@ async def echo(ctx, txt: Annotated[str, discord.Option()]):
cmd = SlashCommand(echo)
bot = discord.Bot()
bot.add_application_command(cmd)
dict_result = cmd.to_dict()
assert (
dict_result.get("options")[0].get("type") == SlashCommandOptionType.string.value
)


def test_typing_annotated_decorator():
Expand All @@ -24,6 +27,12 @@ def test_typing_annotated_decorator():
async def echo(ctx, txt: Annotated[str, discord.Option(description="Some text")]):
await ctx.respond(txt)

dict_result = echo.to_dict()

option = dict_result.get("options")[0]
assert option.get("type") == SlashCommandOptionType.string.value
assert option.get("description") == "Some text"


def test_typing_annotated_cog():
class echoCog(discord.Cog):
Expand All @@ -38,7 +47,14 @@ async def echo(
await ctx.respond(txt)

bot = discord.Bot()
bot.add_cog(echoCog(bot))
cog = echoCog(bot)
bot.add_cog(cog)

dict_result = cog.echo.to_dict()

option = dict_result.get("options")[0]
assert option.get("type") == SlashCommandOptionType.string.value
assert option.get("description") == "Some text"


def test_typing_annotated_cog_slashgroup():
Expand All @@ -56,7 +72,14 @@ async def echo(
await ctx.respond(txt)

bot = discord.Bot()
bot.add_cog(echoCog(bot))
cog = echoCog(bot)
bot.add_cog(cog)

dict_result = cog.echo.to_dict()

option = dict_result.get("options")[0]
assert option.get("type") == SlashCommandOptionType.string.value
assert option.get("description") == "Some text"


def test_typing_annotated_optional():
Expand All @@ -67,6 +90,11 @@ async def echo(ctx, txt: Annotated[Optional[str], discord.Option()]):
bot = discord.Bot()
bot.add_application_command(cmd)

dict_result = cmd.to_dict()

option = dict_result.get("options")[0]
assert option.get("type") == SlashCommandOptionType.string.value


def test_no_annotation():
async def echo(ctx, txt: str):
Expand All @@ -76,6 +104,11 @@ async def echo(ctx, txt: str):
bot = discord.Bot()
bot.add_application_command(cmd)

dict_result = cmd.to_dict()

option = dict_result.get("options")[0]
assert option.get("type") == SlashCommandOptionType.string.value


def test_annotated_no_option():
async def echo(ctx, txt: Annotated[str, "..."]):
Expand All @@ -84,3 +117,8 @@ async def echo(ctx, txt: Annotated[str, "..."]):
cmd = SlashCommand(echo)
bot = discord.Bot()
bot.add_application_command(cmd)

dict_result = cmd.to_dict()

option = dict_result.get("options")[0]
assert option.get("type") == SlashCommandOptionType.string.value
Loading