Browse Source

Add validation

pull/10494/head
Soheab_ 4 days ago
parent
commit
eefc8008f0
  1. 4
      discord/app_commands/commands.py
  2. 6
      discord/components.py
  3. 18
      discord/ui/file_upload.py
  4. 28
      discord/utils.py

4
discord/app_commands/commands.py

@ -68,6 +68,7 @@ from ..utils import (
_iscoroutinefunction,
_shorten,
_to_kebab_case,
_validate_discord_file_types,
)
if TYPE_CHECKING:
@ -387,7 +388,8 @@ def _populate_file_types(params: Dict[str, CommandParameter], file_types: Dict[s
if not isinstance(types, (list, tuple)) or not all(isinstance(ft, (str, FileType)) for ft in types):
raise TypeError('file_types must be a list of strings and FileType enums')
param.file_types = [ft.value if isinstance(ft, FileType) else ft for ft in types]
_validate_discord_file_types(types)
param.file_types = types
if file_types:
first = next(iter(file_types))

6
discord/components.py

@ -32,6 +32,7 @@ from typing import (
TYPE_CHECKING,
Tuple,
Union,
Sequence,
)
from .asset import AssetMixin
@ -44,6 +45,7 @@ from .enums import (
SelectDefaultValueType,
SeparatorSpacing,
MediaItemLoadingState,
FileType,
)
from .flags import AttachmentFlags
from .colour import Colour
@ -1491,7 +1493,7 @@ class FileUploadComponent(Component):
self.max_values: int = data.get('max_values', 1)
self.required: bool = data.get('required', True)
self.id: Optional[int] = data.get('id')
self.file_types: List[str] = data.get('file_types', [])
self.file_types: Sequence[Union[str, FileType]] = data.get('file_types', [])
@property
def type(self) -> Literal[ComponentType.file_upload]:
@ -1509,7 +1511,7 @@ class FileUploadComponent(Component):
if self.id is not None:
payload['id'] = self.id
if self.file_types:
payload['file_types'] = self.file_types
payload['file_types'] = [ft.value if isinstance(ft, FileType) else ft for ft in self.file_types]
return payload

18
discord/ui/file_upload.py

@ -27,7 +27,7 @@ from typing import TYPE_CHECKING, Any, List, Literal, Optional, Sequence, Tuple,
import os
from ..utils import MISSING
from ..utils import MISSING, _validate_discord_file_types
from ..components import FileUploadComponent
from ..enums import ComponentType, FileType
from .item import Item
@ -116,13 +116,16 @@ class FileUpload(Item[V]):
if not isinstance(custom_id, str):
raise TypeError(f'expected custom_id to be str not {custom_id.__class__.__name__}')
if file_types:
_validate_discord_file_types(file_types)
self._underlying: FileUploadComponent = FileUploadComponent._raw_construct(
id=id,
custom_id=custom_id,
max_values=max_values,
min_values=min_values,
required=required,
file_types=[ft.value if isinstance(ft, FileType) else ft for ft in file_types] if file_types is not None else [],
file_types=file_types if file_types else [],
)
self.id = id
self._values: List[Attachment] = []
@ -186,7 +189,7 @@ class FileUpload(Item[V]):
self._underlying.required = bool(value)
@property
def file_types(self) -> List[str]:
def file_types(self) -> List[Union[str, FileType]]:
"""List[:class:`str`]: A list of file types that are allowed to be uploaded for this component.
When setting this property, see the documentation for this parameter in the :class:`.FileUpload`
@ -194,14 +197,15 @@ class FileUpload(Item[V]):
.. versionadded:: 2.8
"""
return self._underlying.file_types
return list(self._underlying.file_types)
@file_types.setter
def file_types(self, value: List[Union[str, FileType]]) -> None:
if not isinstance(value, list) or not all(isinstance(ft, (str, FileType)) for ft in value):
def file_types(self, value: Sequence[Union[str, FileType]]) -> None:
if not isinstance(value, (list, tuple)) or not all(isinstance(ft, (str, FileType)) for ft in value):
raise TypeError('file_types must be a list of str or FileType')
self._underlying.file_types = [ft.value if isinstance(ft, FileType) else ft for ft in value]
_validate_discord_file_types(value)
self._underlying.file_types = list(value)
@property
def width(self) -> int:

28
discord/utils.py

@ -1537,6 +1537,34 @@ def _format_call_duration(duration: datetime.timedelta) -> str:
return formatted
if TYPE_CHECKING:
from .enums import FileType
DISCORD_FILE_TYPES_RE = re.compile(r'^\.[\w\-\.]+$', re.IGNORECASE)
def _validate_discord_file_types(exts: Sequence[Union[FileType, str]], /) -> None:
if len(exts) > 10:
raise ValueError(
f'Too many file extensions provided. Must be 10 or less, got {len(exts)}.',
)
for ext in exts:
# don't need to validate the presets (FileType enum) since they are guaranteed to be valid
if not isinstance(ext, str):
continue
if len(ext) > 16:
raise ValueError(
f'File extension {ext!r} is too long. Must be 16 characters or less.',
)
if not DISCORD_FILE_TYPES_RE.match(ext):
raise ValueError(
f'File extension {ext!r} is invalid. It must start with a dot and contain only alphanumeric characters, hyphens, or underscores.',
)
class _RawReprMixin:
__slots__: Tuple[str, ...] = ()

Loading…
Cancel
Save