Repository: Pycord-Development/pycord

Issue:
Can not register non-english slash command
### Summary

when slash command's name is non english, command cannot not register.

### Reproduction Steps

1. make a slash command has non-english name
2. run the bot process
3. it makes error!

### Minimal Reproducible Code

```python
@slash_command(name="테스트")
    async def test(self, ctx: ApplicationContext):
        pass
```


### Expected Results

The command should register.

like this
![image](https://user-images.githubusercontent.com/77449586/143613131-dc1145b6-29fb-4356-8af1-d7729419b27c.png)


### Actual Results

Traceback (most recent call last):
  File "C:\Users\user\AppData\Local\Programs\Python\Python39\lib\site-packages\discord\ext\commands\bot.py", line 548, in _load_from_module_spec
    spec.loader.exec_module(lib)  # type: ignore
  File "<frozen importlib._bootstrap_external>", line 850, in exec_module
  File "<frozen importlib._bootstrap>", line 228, in _call_with_frames_removed
  File "d:\GitHub\user\cmds\music\__init__.py", line 1, in <module>
    from .music import Music
  File "d:\GitHub\user\cmds\music\music.py", line 31, in <module>
    class Music(commands.Cog):
  File "d:\GitHub\user\cmds\music\music.py", line 70, in Music
    async def test(
  File "C:\Users\user\AppData\Local\Programs\Python\Python39\lib\site-packages\discord\commands\commands.py", line 1110, in decorator
    return cls(func, **attrs)
  File "C:\Users\user\AppData\Local\Programs\Python\Python39\lib\site-packages\discord\commands\commands.py", line 376, in __init__
    validate_chat_input_name(name)
  File "C:\Users\user\AppData\Local\Programs\Python\Python39\lib\site-packages\discord\commands\commands.py", line 1133, in validate_chat_input_name
    raise ValidationError("Name of a chat input command must be lowercase.")
discord.errors.ValidationError: Name of a chat input command must be lowercase.

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "C:\Users\user\AppData\Local\Programs\Python\Python39\lib\site-packages\discord\ext\commands\core.py", line 173, in wrapped
    ret = await coro(*args, **kwargs)
  File "d:\GitHub\user\main.py", line 65, in bot_wakeup
    raise e
  File "d:\GitHub\user\main.py", line 62, in bot_wakeup
    bot.load_extension(extension)
  File "C:\Users\user\AppData\Local\Programs\Python\Python39\lib\site-packages\discord\ext\commands\bot.py", line 620, in load_extension
    self._load_from_module_spec(spec, name)
  File "C:\Users\user\AppData\Local\Programs\Python\Python39\lib\site-packages\discord\ext\commands\bot.py", line 551, in _load_from_module_spec
    raise discord.ExtensionFailed(key, e) from e
discord.errors.ExtensionFailed: Extension 'cmds.music' raised an error: ValidationError: Name of a chat input command must be lowercase.

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "C:\Users\user\AppData\Local\Programs\Python\Python39\lib\site-packages\discord\ext\commands\bot.py", line 882, in invoke
    await ctx.command.invoke(ctx)
  File "C:\Users\user\AppData\Local\Programs\Python\Python39\lib\site-packages\discord\ext\commands\core.py", line 910, in invoke
    await injected(*ctx.args, **ctx.kwargs)
  File "C:\Users\user\AppData\Local\Programs\Python\Python39\lib\site-packages\discord\ext\commands\core.py", line 182, in wrapped
    raise CommandInvokeError(exc) from exc
discord.ext.commands.errors.CommandInvokeError: Command raised an exception: ExtensionFailed: Extension 'cmds.music' raised an error: ValidationError: Name of a chat input command must be lowercase.

### Intents

member

### System Information

- Python v3.9.8-final
- py-cord v2.0.0-alpha
    - py-cord pkg_resources: v2.0.0a4473+g6b1822ee
- aiohttp v3.7.4.post0
- system info: Windows 10 10.0.22000

### Checklist

- [X] I have searched the open issues for duplicates.
- [X] I have shown the entire traceback, if possible.
- [X] I have removed my token from display, if visible.

### Additional Context

_No response_
Can not register non-english slash command
### Summary

when slash command's name is non english, command cannot not register.

### Reproduction Steps

1. make a slash command has non-english name
2. run the bot process
3. it makes error!

### Minimal Reproducible Code

```python
@slash_command(name="테스트")
    async def test(self, ctx: ApplicationContext):
        pass
```


### Expected Results

The command should register.

like this
![image](https://user-images.githubusercontent.com/77449586/143613131-dc1145b6-29fb-4356-8af1-d7729419b27c.png)


### Actual Results

Traceback (most recent call last):
  File "C:\Users\user\AppData\Local\Programs\Python\Python39\lib\site-packages\discord\ext\commands\bot.py", line 548, in _load_from_module_spec
    spec.loader.exec_module(lib)  # type: ignore
  File "<frozen importlib._bootstrap_external>", line 850, in exec_module
  File "<frozen importlib._bootstrap>", line 228, in _call_with_frames_removed
  File "d:\GitHub\user\cmds\music\__init__.py", line 1, in <module>
    from .music import Music
  File "d:\GitHub\user\cmds\music\music.py", line 31, in <module>
    class Music(commands.Cog):
  File "d:\GitHub\user\cmds\music\music.py", line 70, in Music
    async def test(
  File "C:\Users\user\AppData\Local\Programs\Python\Python39\lib\site-packages\discord\commands\commands.py", line 1110, in decorator
    return cls(func, **attrs)
  File "C:\Users\user\AppData\Local\Programs\Python\Python39\lib\site-packages\discord\commands\commands.py", line 376, in __init__
    validate_chat_input_name(name)
  File "C:\Users\user\AppData\Local\Programs\Python\Python39\lib\site-packages\discord\commands\commands.py", line 1133, in validate_chat_input_name
    raise ValidationError("Name of a chat input command must be lowercase.")
discord.errors.ValidationError: Name of a chat input command must be lowercase.

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "C:\Users\user\AppData\Local\Programs\Python\Python39\lib\site-packages\discord\ext\commands\core.py", line 173, in wrapped
    ret = await coro(*args, **kwargs)
  File "d:\GitHub\user\main.py", line 65, in bot_wakeup
    raise e
  File "d:\GitHub\user\main.py", line 62, in bot_wakeup
    bot.load_extension(extension)
  File "C:\Users\user\AppData\Local\Programs\Python\Python39\lib\site-packages\discord\ext\commands\bot.py", line 620, in load_extension
    self._load_from_module_spec(spec, name)
  File "C:\Users\user\AppData\Local\Programs\Python\Python39\lib\site-packages\discord\ext\commands\bot.py", line 551, in _load_from_module_spec
    raise discord.ExtensionFailed(key, e) from e
discord.errors.ExtensionFailed: Extension 'cmds.music' raised an error: ValidationError: Name of a chat input command must be lowercase.

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "C:\Users\user\AppData\Local\Programs\Python\Python39\lib\site-packages\discord\ext\commands\bot.py", line 882, in invoke
    await ctx.command.invoke(ctx)
  File "C:\Users\user\AppData\Local\Programs\Python\Python39\lib\site-packages\discord\ext\commands\core.py", line 910, in invoke
    await injected(*ctx.args, **ctx.kwargs)
  File "C:\Users\user\AppData\Local\Programs\Python\Python39\lib\site-packages\discord\ext\commands\core.py", line 182, in wrapped
    raise CommandInvokeError(exc) from exc
discord.ext.commands.errors.CommandInvokeError: Command raised an exception: ExtensionFailed: Extension 'cmds.music' raised an error: ValidationError: Name of a chat input command must be lowercase.

### Intents

member

### System Information

- Python v3.9.8-final
- py-cord v2.0.0-alpha
    - py-cord pkg_resources: v2.0.0a4473+g6b1822ee
- aiohttp v3.7.4.post0
- system info: Windows 10 10.0.22000

### Checklist

- [X] I have searched the open issues for duplicates.
- [X] I have shown the entire traceback, if possible.
- [X] I have removed my token from display, if visible.

### Additional Context

_No response_


Discussion:
This is a discord bug.
Like a picture above, It's possible on discord API
I think it is a matter with `<str>.islower()` return False when the string is not starts with english.
Kk. Still I remember some discussions that non English names are not really stable.

Setting this to low prio for now.
That'll do, Thx!
![Screen Shot 2021-12-02 at 11 07 39 AM](https://user-images.githubusercontent.com/71356958/144469376-b2ebcd92-164d-40ca-b59e-ed9ad800d7e8.png)
Made a patch, should be merged soon.

This is a discord bug.
Like a picture above, It's possible on discord API
I think it is a matter with `<str>.islower()` return False when the string is not starts with english.
Kk. Still I remember some discussions that non English names are not really stable.

Setting this to low prio for now.
That'll do, Thx!
![Screen Shot 2021-12-02 at 11 07 39 AM](https://user-images.githubusercontent.com/71356958/144469376-b2ebcd92-164d-40ca-b59e-ed9ad800d7e8.png)
Made a patch, should be merged soon.


Resolving patch:
diff --git a/discord/commands/commands.py b/discord/commands/commands.py
--- a/discord/commands/commands.py
+++ b/discord/commands/commands.py
@@ -26,21 +26,22 @@
 from __future__ import annotations
 
 import asyncio
-import types
 import functools
 import inspect
+import re
+import types
 from collections import OrderedDict
 from typing import Any, Callable, Dict, List, Optional, Union, TYPE_CHECKING
 
+from .context import ApplicationContext, AutocompleteContext
+from .errors import ApplicationCommandError, CheckFailure, ApplicationCommandInvokeError
+from .permissions import Permission
 from ..enums import SlashCommandOptionType, ChannelType
+from ..errors import ValidationError, ClientException
 from ..member import Member
-from ..user import User
 from ..message import Message
-from .context import ApplicationContext, AutocompleteContext
+from ..user import User
 from ..utils import find, get_or_fetch, async_all
-from ..errors import ValidationError, ClientException
-from .errors import ApplicationCommandError, CheckFailure, ApplicationCommandInvokeError
-from .permissions import Permission
 
 __all__ = (
     "_BaseCommand",
@@ -60,8 +61,8 @@
     "MessageCommand",
 )
 
-if TYPE_CHECKING: 
-    from ..interactions import Interaction
+if TYPE_CHECKING:
+    pass
 
 def wrap_callback(coro):
     @functools.wraps(coro)
@@ -459,6 +460,9 @@ def _parse_options(self, params) -> List[Option]:
                 option.name = p_name
             option._parameter_name = p_name
 
+            validate_chat_input_name(option.name)
+            validate_chat_input_description(option.description)
+
             final_options.append(option)
 
         return final_options
@@ -640,7 +644,7 @@ def __init__(
             minmax_types = (int, float, type(None))
         else:
             minmax_types = (type(None),)
-        minmax_typehint = Optional[Union[minmax_types]] # type: ignore
+        minmax_typehint = Optional[Union[minmax_types]]  # type: ignore
 
         self.min_value: minmax_typehint = kwargs.pop("min_value", None)
         self.max_value: minmax_typehint = kwargs.pop("max_value", None)
@@ -1123,24 +1127,33 @@ def command(**kwargs):
     """
     return application_command(**kwargs)
 
+
+docs = "https://discord.com/developers/docs"
+
+
 # Validation
 def validate_chat_input_name(name: Any):
+    # Must meet the regex ^[\w-]{1,32}$
     if not isinstance(name, str):
-        raise TypeError("Name of a command must be a string.")
-    if " " in name:
-        raise ValidationError("Name of a chat input command cannot have spaces.")
-    if not name.islower():
-        raise ValidationError("Name of a chat input command must be lowercase.")
-    if len(name) > 32 or len(name) < 1:
+        raise TypeError(f"Chat input command names and options must be of type str. Received {name}")
+    if not re.match(r"^[\w-]{1,32}$", name):
+        raise ValidationError(
+            r'Chat input command names and options must follow the regex "^[\w-]{1,32}$". For more information, see '
+            f"{docs}/interactions/application-commands#application-command-object-application-command-naming. Received "
+            f"{name}"
+        )
+    if not 1 <= len(name) <= 32:
         raise ValidationError(
-            "Name of a chat input command must be less than 32 characters and non empty."
+            f"Chat input command names and options must be 1-32 characters long. Received {name}"
         )
+    if not name.lower() == name:  # Can't use islower() as it fails if none of the chars can be lower. See #512.
+        raise ValidationError(f"Chat input command names and options must be lowercase. Received {name}")
 
 
 def validate_chat_input_description(description: Any):
     if not isinstance(description, str):
-        raise TypeError("Description of a command must be a string.")
-    if len(description) > 100 or len(description) < 1:
+        raise TypeError(f"Command description must be of type str. Received {description}")
+    if not 1 <= len(description) <= 100:
         raise ValidationError(
-            "Description of a chat input command must be less than 100 characters and non empty."
+            f"Command description must be 1-100 characters long. Received {description}"
         )


Test patch: