Skip to content

Commit

Permalink
Support for typing.Literal
Browse files Browse the repository at this point in the history
  • Loading branch information
AlexFlipnote committed Jan 5, 2025
1 parent 4ac4ed9 commit 952257e
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 1 deletion.
2 changes: 1 addition & 1 deletion discord_http/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
__version__ = "2.0.1"
__version__ = "2.0.2"

# flake8: noqa: F401
from .asset import *
Expand Down
15 changes: 15 additions & 0 deletions discord_http/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,18 @@ def __init__(
self.__list_choices.append(parameter.name)
ptype = origin.type

# If literal, replicate Choice
elif origin is Literal:
self.__list_choices.append(parameter.name)
ptype = CommandOptionType.string

if not getattr(self.command, "__choices_params__", {}):
self.command.__choices_params__ = {}

self.command.__choices_params__[parameter.name] = {
str(g): str(g) for g in parameter.annotation.__args__
}

# PyRight may not recognize 'Range' due to dynamic typing.
# Assuming 'origin' is a Range object.
elif isinstance(origin, Range): # type: ignore[arg-type]
Expand Down Expand Up @@ -1019,6 +1031,9 @@ def __init__(self, key: ChoiceT, value: ChoiceT):
self.value: ChoiceT = value
self.type: CommandOptionType = CommandOptionType.string

def __str__(self) -> str:
return str(self.key)

def __class_getitem__(cls, obj):
if isinstance(obj, tuple):
raise TypeError("Choice can only take one type")
Expand Down
6 changes: 6 additions & 0 deletions tests/manual_testing.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import secrets

from datetime import time, timedelta
from typing import Literal

from discord_http import (
Context, Embed, File, Member,
Expand Down Expand Up @@ -647,6 +648,11 @@ async def test_channel(ctx: Context, channel: VoiceChannel):
return ctx.response.send_message(f"You chose {channel} {repr(channel)}")


@client.command(name="test_literal")
async def test_literal(ctx: Context, choice: Literal["very", "Nice", "test"]):
return ctx.response.send_message(f"You chose {choice}")


@client.command()
async def test_search_member(ctx: Context, query: str):
members = await ctx.guild.search_members(query)
Expand Down

0 comments on commit 952257e

Please sign in to comment.