mirror of
https://github.com/Rapptz/discord.py.git
synced 2025-06-07 20:28:38 +00:00
Typehint discord.Embed and introduce discord.types subpackage
The discord.types subpackage is currently only used to do type hinting of API payloads, it's very much incomplete right now and it'll be a rather long process. discord.Embed was typehinted and formatted using black.
This commit is contained in:
parent
bda3afcad7
commit
23fe6b46dd
@ -22,7 +22,10 @@ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|||||||
DEALINGS IN THE SOFTWARE.
|
DEALINGS IN THE SOFTWARE.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
import datetime
|
import datetime
|
||||||
|
from typing import Any, Dict, Final, List, Protocol, TYPE_CHECKING, Type, TypeVar, Union
|
||||||
|
|
||||||
from . import utils
|
from . import utils
|
||||||
from .colour import Colour
|
from .colour import Colour
|
||||||
@ -31,32 +34,75 @@ __all__ = (
|
|||||||
'Embed',
|
'Embed',
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class _EmptyEmbed:
|
class _EmptyEmbed:
|
||||||
def __bool__(self):
|
def __bool__(self) -> bool:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self) -> str:
|
||||||
return 'Embed.Empty'
|
return 'Embed.Empty'
|
||||||
|
|
||||||
def __len__(self):
|
def __len__(self) -> int:
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
EmptyEmbed = _EmptyEmbed()
|
|
||||||
|
EmptyEmbed: Final = _EmptyEmbed()
|
||||||
|
|
||||||
|
|
||||||
class EmbedProxy:
|
class EmbedProxy:
|
||||||
def __init__(self, layer):
|
def __init__(self, layer: Dict[str, Any]):
|
||||||
self.__dict__.update(layer)
|
self.__dict__.update(layer)
|
||||||
|
|
||||||
def __len__(self):
|
def __len__(self) -> int:
|
||||||
return len(self.__dict__)
|
return len(self.__dict__)
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self) -> str:
|
||||||
inner = ', '.join((f'{k}={v!r}' for k, v in self.__dict__.items() if not k.startswith('_')))
|
inner = ', '.join((f'{k}={v!r}' for k, v in self.__dict__.items() if not k.startswith('_')))
|
||||||
return f'EmbedProxy({inner})'
|
return f'EmbedProxy({inner})'
|
||||||
|
|
||||||
def __getattr__(self, attr):
|
def __getattr__(self, attr: str) -> _EmptyEmbed:
|
||||||
return EmptyEmbed
|
return EmptyEmbed
|
||||||
|
|
||||||
|
|
||||||
|
E = TypeVar('E', bound='Embed')
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from discord.types.common import Embed as EmbedData, EmbedType
|
||||||
|
|
||||||
|
T = TypeVar('T')
|
||||||
|
MaybeEmpty = Union[T, _EmptyEmbed]
|
||||||
|
|
||||||
|
class _EmbedFooterProxy(Protocol):
|
||||||
|
text: MaybeEmpty[str]
|
||||||
|
icon_url: MaybeEmpty[str]
|
||||||
|
|
||||||
|
class _EmbedFieldProxy(Protocol):
|
||||||
|
name: MaybeEmpty[str]
|
||||||
|
value: MaybeEmpty[str]
|
||||||
|
inline: bool
|
||||||
|
|
||||||
|
class _EmbedMediaProxy(Protocol):
|
||||||
|
url: MaybeEmpty[str]
|
||||||
|
proxy_url: MaybeEmpty[str]
|
||||||
|
height: MaybeEmpty[int]
|
||||||
|
width: MaybeEmpty[int]
|
||||||
|
|
||||||
|
class _EmbedVideoProxy(Protocol):
|
||||||
|
url: MaybeEmpty[str]
|
||||||
|
height: MaybeEmpty[int]
|
||||||
|
width: MaybeEmpty[int]
|
||||||
|
|
||||||
|
class _EmbedProviderProxy(Protocol):
|
||||||
|
name: MaybeEmpty[str]
|
||||||
|
url: MaybeEmpty[str]
|
||||||
|
|
||||||
|
class _EmbedAuthorProxy(Protocol):
|
||||||
|
name: MaybeEmpty[str]
|
||||||
|
url: MaybeEmpty[str]
|
||||||
|
icon_url: MaybeEmpty[str]
|
||||||
|
proxy_icon_url: MaybeEmpty[str]
|
||||||
|
|
||||||
|
|
||||||
class Embed:
|
class Embed:
|
||||||
"""Represents a Discord embed.
|
"""Represents a Discord embed.
|
||||||
|
|
||||||
@ -108,24 +154,41 @@ class Embed:
|
|||||||
to denote that the value or attribute is empty.
|
to denote that the value or attribute is empty.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__slots__ = ('title', 'url', 'type', '_timestamp', '_colour', '_footer',
|
__slots__ = (
|
||||||
'_image', '_thumbnail', '_video', '_provider', '_author',
|
'title',
|
||||||
'_fields', 'description')
|
'url',
|
||||||
|
'type',
|
||||||
|
'_timestamp',
|
||||||
|
'_colour',
|
||||||
|
'_footer',
|
||||||
|
'_image',
|
||||||
|
'_thumbnail',
|
||||||
|
'_video',
|
||||||
|
'_provider',
|
||||||
|
'_author',
|
||||||
|
'_fields',
|
||||||
|
'description',
|
||||||
|
)
|
||||||
|
|
||||||
Empty = EmptyEmbed
|
Empty: Final = EmptyEmbed
|
||||||
|
|
||||||
def __init__(self, **kwargs):
|
def __init__(
|
||||||
# swap the colour/color aliases
|
self,
|
||||||
try:
|
*,
|
||||||
colour = kwargs['colour']
|
colour: Union[int, Colour, _EmptyEmbed] = EmptyEmbed,
|
||||||
except KeyError:
|
color: Union[int, Colour, _EmptyEmbed] = EmptyEmbed,
|
||||||
colour = kwargs.get('color', EmptyEmbed)
|
title: MaybeEmpty[str] = EmptyEmbed,
|
||||||
|
type: EmbedType = 'rich',
|
||||||
|
url: MaybeEmpty[str] = EmptyEmbed,
|
||||||
|
description: MaybeEmpty[str] = EmptyEmbed,
|
||||||
|
timestamp: datetime.datetime = None,
|
||||||
|
):
|
||||||
|
|
||||||
self.colour = colour
|
self.colour = colour if colour is not EmptyEmbed else color
|
||||||
self.title = kwargs.get('title', EmptyEmbed)
|
self.title = title
|
||||||
self.type = kwargs.get('type', 'rich')
|
self.type = type
|
||||||
self.url = kwargs.get('url', EmptyEmbed)
|
self.url = url
|
||||||
self.description = kwargs.get('description', EmptyEmbed)
|
self.description = description
|
||||||
|
|
||||||
if self.title is not EmptyEmbed:
|
if self.title is not EmptyEmbed:
|
||||||
self.title = str(self.title)
|
self.title = str(self.title)
|
||||||
@ -136,17 +199,13 @@ class Embed:
|
|||||||
if self.url is not EmptyEmbed:
|
if self.url is not EmptyEmbed:
|
||||||
self.url = str(self.url)
|
self.url = str(self.url)
|
||||||
|
|
||||||
try:
|
if timestamp:
|
||||||
timestamp = kwargs['timestamp']
|
|
||||||
except KeyError:
|
|
||||||
pass
|
|
||||||
else:
|
|
||||||
if timestamp.tzinfo is None:
|
if timestamp.tzinfo is None:
|
||||||
timestamp = timestamp.astimezone()
|
timestamp = timestamp.astimezone()
|
||||||
self.timestamp = timestamp
|
self.timestamp = timestamp
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_dict(cls, data):
|
def from_dict(cls: Type[E], data: EmbedData) -> E:
|
||||||
"""Converts a :class:`dict` to a :class:`Embed` provided it is in the
|
"""Converts a :class:`dict` to a :class:`Embed` provided it is in the
|
||||||
format that Discord expects it to be in.
|
format that Discord expects it to be in.
|
||||||
|
|
||||||
@ -162,7 +221,7 @@ class Embed:
|
|||||||
The dictionary to convert into an embed.
|
The dictionary to convert into an embed.
|
||||||
"""
|
"""
|
||||||
# we are bypassing __init__ here since it doesn't apply here
|
# we are bypassing __init__ here since it doesn't apply here
|
||||||
self = cls.__new__(cls)
|
self: E = cls.__new__(cls)
|
||||||
|
|
||||||
# fill in the basic fields
|
# fill in the basic fields
|
||||||
|
|
||||||
@ -202,11 +261,11 @@ class Embed:
|
|||||||
|
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def copy(self):
|
def copy(self: E) -> E:
|
||||||
"""Returns a shallow copy of the embed."""
|
"""Returns a shallow copy of the embed."""
|
||||||
return Embed.from_dict(self.to_dict())
|
return self.__class__.from_dict(self.to_dict())
|
||||||
|
|
||||||
def __len__(self):
|
def __len__(self) -> int:
|
||||||
total = len(self.title) + len(self.description)
|
total = len(self.title) + len(self.description)
|
||||||
for field in getattr(self, '_fields', []):
|
for field in getattr(self, '_fields', []):
|
||||||
total += len(field['name']) + len(field['value'])
|
total += len(field['name']) + len(field['value'])
|
||||||
@ -227,8 +286,9 @@ class Embed:
|
|||||||
|
|
||||||
return total
|
return total
|
||||||
|
|
||||||
def __bool__(self):
|
def __bool__(self) -> bool:
|
||||||
return any((
|
return any(
|
||||||
|
(
|
||||||
self.title,
|
self.title,
|
||||||
self.url,
|
self.url,
|
||||||
self.description,
|
self.description,
|
||||||
@ -241,14 +301,15 @@ class Embed:
|
|||||||
self.image,
|
self.image,
|
||||||
self.provider,
|
self.provider,
|
||||||
self.video,
|
self.video,
|
||||||
))
|
)
|
||||||
|
)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def colour(self):
|
def colour(self) -> MaybeEmpty[Colour]:
|
||||||
return getattr(self, '_colour', EmptyEmbed)
|
return getattr(self, '_colour', EmptyEmbed)
|
||||||
|
|
||||||
@colour.setter
|
@colour.setter
|
||||||
def colour(self, value):
|
def colour(self, value: Union[int, Colour, _EmptyEmbed]): # type: ignore
|
||||||
if isinstance(value, (Colour, _EmptyEmbed)):
|
if isinstance(value, (Colour, _EmptyEmbed)):
|
||||||
self._colour = value
|
self._colour = value
|
||||||
elif isinstance(value, int):
|
elif isinstance(value, int):
|
||||||
@ -259,27 +320,27 @@ class Embed:
|
|||||||
color = colour
|
color = colour
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def timestamp(self):
|
def timestamp(self) -> MaybeEmpty[datetime.datetime]:
|
||||||
return getattr(self, '_timestamp', EmptyEmbed)
|
return getattr(self, '_timestamp', EmptyEmbed)
|
||||||
|
|
||||||
@timestamp.setter
|
@timestamp.setter
|
||||||
def timestamp(self, value):
|
def timestamp(self, value: MaybeEmpty[datetime.datetime]):
|
||||||
if isinstance(value, (datetime.datetime, _EmptyEmbed)):
|
if isinstance(value, (datetime.datetime, _EmptyEmbed)):
|
||||||
self._timestamp = value
|
self._timestamp = value
|
||||||
else:
|
else:
|
||||||
raise TypeError(f"Expected datetime.datetime or Embed.Empty received {value.__class__.__name__} instead")
|
raise TypeError(f"Expected datetime.datetime or Embed.Empty received {value.__class__.__name__} instead")
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def footer(self):
|
def footer(self) -> _EmbedFooterProxy:
|
||||||
"""Union[:class:`EmbedProxy`, :attr:`Empty`]: Returns an ``EmbedProxy`` denoting the footer contents.
|
"""Returns an ``EmbedProxy`` denoting the footer contents.
|
||||||
|
|
||||||
See :meth:`set_footer` for possible values you can access.
|
See :meth:`set_footer` for possible values you can access.
|
||||||
|
|
||||||
If the attribute has no value then :attr:`Empty` is returned.
|
If the attribute has no value then :attr:`Empty` is returned.
|
||||||
"""
|
"""
|
||||||
return EmbedProxy(getattr(self, '_footer', {}))
|
return EmbedProxy(getattr(self, '_footer', {})) # type: ignore
|
||||||
|
|
||||||
def set_footer(self, *, text=EmptyEmbed, icon_url=EmptyEmbed):
|
def set_footer(self: E, *, text: MaybeEmpty[str] = EmptyEmbed, icon_url: MaybeEmpty[str] = EmptyEmbed) -> E:
|
||||||
"""Sets the footer for the embed content.
|
"""Sets the footer for the embed content.
|
||||||
|
|
||||||
This function returns the class instance to allow for fluent-style
|
This function returns the class instance to allow for fluent-style
|
||||||
@ -303,8 +364,8 @@ class Embed:
|
|||||||
return self
|
return self
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def image(self):
|
def image(self) -> _EmbedMediaProxy:
|
||||||
"""Union[:class:`EmbedProxy`, :attr:`Empty`]: Returns an ``EmbedProxy`` denoting the image contents.
|
"""Returns an ``EmbedProxy`` denoting the image contents.
|
||||||
|
|
||||||
Possible attributes you can access are:
|
Possible attributes you can access are:
|
||||||
|
|
||||||
@ -315,9 +376,9 @@ class Embed:
|
|||||||
|
|
||||||
If the attribute has no value then :attr:`Empty` is returned.
|
If the attribute has no value then :attr:`Empty` is returned.
|
||||||
"""
|
"""
|
||||||
return EmbedProxy(getattr(self, '_image', {}))
|
return EmbedProxy(getattr(self, '_image', {})) # type: ignore
|
||||||
|
|
||||||
def set_image(self, *, url):
|
def set_image(self: E, *, url: MaybeEmpty[str]) -> E:
|
||||||
"""Sets the image for the embed content.
|
"""Sets the image for the embed content.
|
||||||
|
|
||||||
This function returns the class instance to allow for fluent-style
|
This function returns the class instance to allow for fluent-style
|
||||||
@ -339,14 +400,14 @@ class Embed:
|
|||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
self._image = {
|
self._image = {
|
||||||
'url': str(url)
|
'url': str(url),
|
||||||
}
|
}
|
||||||
|
|
||||||
return self
|
return self
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def thumbnail(self):
|
def thumbnail(self) -> _EmbedMediaProxy:
|
||||||
"""Union[:class:`EmbedProxy`, :attr:`Empty`]: Returns an ``EmbedProxy`` denoting the thumbnail contents.
|
"""Returns an ``EmbedProxy`` denoting the thumbnail contents.
|
||||||
|
|
||||||
Possible attributes you can access are:
|
Possible attributes you can access are:
|
||||||
|
|
||||||
@ -357,9 +418,9 @@ class Embed:
|
|||||||
|
|
||||||
If the attribute has no value then :attr:`Empty` is returned.
|
If the attribute has no value then :attr:`Empty` is returned.
|
||||||
"""
|
"""
|
||||||
return EmbedProxy(getattr(self, '_thumbnail', {}))
|
return EmbedProxy(getattr(self, '_thumbnail', {})) # type: ignore
|
||||||
|
|
||||||
def set_thumbnail(self, *, url):
|
def set_thumbnail(self: E, *, url: MaybeEmpty[str]) -> E:
|
||||||
"""Sets the thumbnail for the embed content.
|
"""Sets the thumbnail for the embed content.
|
||||||
|
|
||||||
This function returns the class instance to allow for fluent-style
|
This function returns the class instance to allow for fluent-style
|
||||||
@ -381,14 +442,14 @@ class Embed:
|
|||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
self._thumbnail = {
|
self._thumbnail = {
|
||||||
'url': str(url)
|
'url': str(url),
|
||||||
}
|
}
|
||||||
|
|
||||||
return self
|
return self
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def video(self):
|
def video(self) -> _EmbedVideoProxy:
|
||||||
"""Union[:class:`EmbedProxy`, :attr:`Empty`]: Returns an ``EmbedProxy`` denoting the video contents.
|
"""Returns an ``EmbedProxy`` denoting the video contents.
|
||||||
|
|
||||||
Possible attributes include:
|
Possible attributes include:
|
||||||
|
|
||||||
@ -398,29 +459,29 @@ class Embed:
|
|||||||
|
|
||||||
If the attribute has no value then :attr:`Empty` is returned.
|
If the attribute has no value then :attr:`Empty` is returned.
|
||||||
"""
|
"""
|
||||||
return EmbedProxy(getattr(self, '_video', {}))
|
return EmbedProxy(getattr(self, '_video', {})) # type: ignore
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def provider(self):
|
def provider(self) -> _EmbedProviderProxy:
|
||||||
"""Union[:class:`EmbedProxy`, :attr:`Empty`]: Returns an ``EmbedProxy`` denoting the provider contents.
|
"""Returns an ``EmbedProxy`` denoting the provider contents.
|
||||||
|
|
||||||
The only attributes that might be accessed are ``name`` and ``url``.
|
The only attributes that might be accessed are ``name`` and ``url``.
|
||||||
|
|
||||||
If the attribute has no value then :attr:`Empty` is returned.
|
If the attribute has no value then :attr:`Empty` is returned.
|
||||||
"""
|
"""
|
||||||
return EmbedProxy(getattr(self, '_provider', {}))
|
return EmbedProxy(getattr(self, '_provider', {})) # type: ignore
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def author(self):
|
def author(self) -> _EmbedAuthorProxy:
|
||||||
"""Union[:class:`EmbedProxy`, :attr:`Empty`]: Returns an ``EmbedProxy`` denoting the author contents.
|
"""Returns an ``EmbedProxy`` denoting the author contents.
|
||||||
|
|
||||||
See :meth:`set_author` for possible values you can access.
|
See :meth:`set_author` for possible values you can access.
|
||||||
|
|
||||||
If the attribute has no value then :attr:`Empty` is returned.
|
If the attribute has no value then :attr:`Empty` is returned.
|
||||||
"""
|
"""
|
||||||
return EmbedProxy(getattr(self, '_author', {}))
|
return EmbedProxy(getattr(self, '_author', {})) # type: ignore
|
||||||
|
|
||||||
def set_author(self, *, name, url=EmptyEmbed, icon_url=EmptyEmbed):
|
def set_author(self: E, *, name: str, url: MaybeEmpty[str] = EmptyEmbed, icon_url: MaybeEmpty[str] = EmptyEmbed) -> E:
|
||||||
"""Sets the author for the embed content.
|
"""Sets the author for the embed content.
|
||||||
|
|
||||||
This function returns the class instance to allow for fluent-style
|
This function returns the class instance to allow for fluent-style
|
||||||
@ -437,7 +498,7 @@ class Embed:
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
self._author = {
|
self._author = {
|
||||||
'name': str(name)
|
'name': str(name),
|
||||||
}
|
}
|
||||||
|
|
||||||
if url is not EmptyEmbed:
|
if url is not EmptyEmbed:
|
||||||
@ -448,7 +509,7 @@ class Embed:
|
|||||||
|
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def remove_author(self):
|
def remove_author(self: E) -> E:
|
||||||
"""Clears embed's author information.
|
"""Clears embed's author information.
|
||||||
|
|
||||||
This function returns the class instance to allow for fluent-style
|
This function returns the class instance to allow for fluent-style
|
||||||
@ -464,16 +525,16 @@ class Embed:
|
|||||||
return self
|
return self
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def fields(self):
|
def fields(self) -> List[_EmbedFieldProxy]:
|
||||||
"""Union[List[:class:`EmbedProxy`], :attr:`Empty`]: Returns a :class:`list` of ``EmbedProxy`` denoting the field contents.
|
"""Union[List[:class:`EmbedProxy`], :attr:`Empty`]: Returns a :class:`list` of ``EmbedProxy`` denoting the field contents.
|
||||||
|
|
||||||
See :meth:`add_field` for possible values you can access.
|
See :meth:`add_field` for possible values you can access.
|
||||||
|
|
||||||
If the attribute has no value then :attr:`Empty` is returned.
|
If the attribute has no value then :attr:`Empty` is returned.
|
||||||
"""
|
"""
|
||||||
return [EmbedProxy(d) for d in getattr(self, '_fields', [])]
|
return [EmbedProxy(d) for d in getattr(self, '_fields', [])] # type: ignore
|
||||||
|
|
||||||
def add_field(self, *, name, value, inline=True):
|
def add_field(self: E, *, name: str, value: str, inline: bool = True) -> E:
|
||||||
"""Adds a field to the embed object.
|
"""Adds a field to the embed object.
|
||||||
|
|
||||||
This function returns the class instance to allow for fluent-style
|
This function returns the class instance to allow for fluent-style
|
||||||
@ -492,7 +553,7 @@ class Embed:
|
|||||||
field = {
|
field = {
|
||||||
'inline': inline,
|
'inline': inline,
|
||||||
'name': str(name),
|
'name': str(name),
|
||||||
'value': str(value)
|
'value': str(value),
|
||||||
}
|
}
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@ -502,7 +563,7 @@ class Embed:
|
|||||||
|
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def insert_field_at(self, index, *, name, value, inline=True):
|
def insert_field_at(self: E, index: int, *, name: str, value: str, inline: bool = True) -> E:
|
||||||
"""Inserts a field before a specified index to the embed.
|
"""Inserts a field before a specified index to the embed.
|
||||||
|
|
||||||
This function returns the class instance to allow for fluent-style
|
This function returns the class instance to allow for fluent-style
|
||||||
@ -525,7 +586,7 @@ class Embed:
|
|||||||
field = {
|
field = {
|
||||||
'inline': inline,
|
'inline': inline,
|
||||||
'name': str(name),
|
'name': str(name),
|
||||||
'value': str(value)
|
'value': str(value),
|
||||||
}
|
}
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@ -535,14 +596,14 @@ class Embed:
|
|||||||
|
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def clear_fields(self):
|
def clear_fields(self) -> None:
|
||||||
"""Removes all fields from this embed."""
|
"""Removes all fields from this embed."""
|
||||||
try:
|
try:
|
||||||
self._fields.clear()
|
self._fields.clear()
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
self._fields = []
|
self._fields = []
|
||||||
|
|
||||||
def remove_field(self, index):
|
def remove_field(self, index: int) -> None:
|
||||||
"""Removes a field at a specified index.
|
"""Removes a field at a specified index.
|
||||||
|
|
||||||
If the index is invalid or out of bounds then the error is
|
If the index is invalid or out of bounds then the error is
|
||||||
@ -563,7 +624,7 @@ class Embed:
|
|||||||
except (AttributeError, IndexError):
|
except (AttributeError, IndexError):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def set_field_at(self, index, *, name, value, inline=True):
|
def set_field_at(self: E, index: int, *, name: str, value: str, inline: bool = True) -> E:
|
||||||
"""Modifies a field to the embed object.
|
"""Modifies a field to the embed object.
|
||||||
|
|
||||||
The index must point to a valid pre-existing field.
|
The index must point to a valid pre-existing field.
|
||||||
@ -598,15 +659,17 @@ class Embed:
|
|||||||
field['inline'] = inline
|
field['inline'] = inline
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def to_dict(self):
|
def to_dict(self) -> EmbedData:
|
||||||
"""Converts this embed object into a dict."""
|
"""Converts this embed object into a dict."""
|
||||||
|
|
||||||
# add in the raw data into the dict
|
# add in the raw data into the dict
|
||||||
|
# fmt: off
|
||||||
result = {
|
result = {
|
||||||
key[1:]: getattr(self, key)
|
key[1:]: getattr(self, key)
|
||||||
for key in self.__slots__
|
for key in self.__slots__
|
||||||
if key[0] == '_' and hasattr(self, key)
|
if key[0] == '_' and hasattr(self, key)
|
||||||
}
|
}
|
||||||
|
# fmt: on
|
||||||
|
|
||||||
# deal with basic convenience wrappers
|
# deal with basic convenience wrappers
|
||||||
|
|
||||||
@ -642,4 +705,4 @@ class Embed:
|
|||||||
if self.title:
|
if self.title:
|
||||||
result['title'] = self.title
|
result['title'] = self.title
|
||||||
|
|
||||||
return result
|
return result # type: ignore
|
||||||
|
10
discord/types/__init__.py
Normal file
10
discord/types/__init__.py
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
"""
|
||||||
|
discord.types
|
||||||
|
~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
Typings for the Discord API
|
||||||
|
|
||||||
|
:copyright: (c) 2015-present Rapptz
|
||||||
|
:license: MIT, see LICENSE for more details.
|
||||||
|
|
||||||
|
"""
|
86
discord/types/common.py
Normal file
86
discord/types/common.py
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
"""
|
||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2015-present Rapptz
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
to deal in the Software without restriction, including without limitation
|
||||||
|
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
|
and/or sell copies of the Software, and to permit persons to whom the
|
||||||
|
Software is furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||||
|
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
DEALINGS IN THE SOFTWARE.
|
||||||
|
"""
|
||||||
|
|
||||||
|
# This file provides typings for shared entities between the Gateway and HTTP API
|
||||||
|
|
||||||
|
from typing import List, Literal, TypedDict
|
||||||
|
|
||||||
|
class _EmbedFooterOptional(TypedDict, total=False):
|
||||||
|
icon_url: str
|
||||||
|
proxy_icon_url: str
|
||||||
|
|
||||||
|
class EmbedFooter(_EmbedFooterOptional):
|
||||||
|
text: str
|
||||||
|
|
||||||
|
class _EmbedFieldOptional(TypedDict, total=False):
|
||||||
|
inline: bool
|
||||||
|
|
||||||
|
class EmbedField(_EmbedFieldOptional):
|
||||||
|
name: str
|
||||||
|
value: str
|
||||||
|
|
||||||
|
class EmbedThumbnail(TypedDict, total=False):
|
||||||
|
url: str
|
||||||
|
proxy_url: str
|
||||||
|
height: int
|
||||||
|
width: int
|
||||||
|
|
||||||
|
class EmbedVideo(TypedDict, total=False):
|
||||||
|
url: str
|
||||||
|
proxy_url: str
|
||||||
|
height: int
|
||||||
|
width: int
|
||||||
|
|
||||||
|
class EmbedImage(TypedDict, total=False):
|
||||||
|
url: str
|
||||||
|
proxy_url: str
|
||||||
|
height: int
|
||||||
|
width: int
|
||||||
|
|
||||||
|
class EmbedProvider(TypedDict, total=False):
|
||||||
|
name: str
|
||||||
|
url: str
|
||||||
|
|
||||||
|
class EmbedAuthor(TypedDict, total=False):
|
||||||
|
name: str
|
||||||
|
url: str
|
||||||
|
icon_url: str
|
||||||
|
proxy_icon_url: str
|
||||||
|
|
||||||
|
EmbedType = Literal['rich', 'image', 'video', 'gifv', 'article', 'link']
|
||||||
|
|
||||||
|
class Embed(TypedDict, total=False):
|
||||||
|
title: str
|
||||||
|
type: EmbedType
|
||||||
|
description: str
|
||||||
|
url: str
|
||||||
|
timestamp: str
|
||||||
|
color: int
|
||||||
|
footer: EmbedFooter
|
||||||
|
image: EmbedImage
|
||||||
|
thumbnail: EmbedThumbnail
|
||||||
|
video: EmbedVideo
|
||||||
|
provider: EmbedProvider
|
||||||
|
author: EmbedAuthor
|
||||||
|
fields: List[EmbedField]
|
2
setup.py
2
setup.py
@ -50,7 +50,7 @@ setup(name='discord.py',
|
|||||||
"Issue tracker": "https://github.com/Rapptz/discord.py/issues",
|
"Issue tracker": "https://github.com/Rapptz/discord.py/issues",
|
||||||
},
|
},
|
||||||
version=version,
|
version=version,
|
||||||
packages=['discord', 'discord.ext.commands', 'discord.ext.tasks'],
|
packages=['discord', 'discord.types', 'discord.ext.commands', 'discord.ext.tasks'],
|
||||||
license='MIT',
|
license='MIT',
|
||||||
description='A Python wrapper for the Discord API',
|
description='A Python wrapper for the Discord API',
|
||||||
long_description=readme,
|
long_description=readme,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user