Merge branch '2.0' into updated-links
This commit is contained in:
commit
432b4d442a
2
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
2
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
@ -6,7 +6,7 @@ body:
|
|||||||
attributes:
|
attributes:
|
||||||
value: >
|
value: >
|
||||||
Thanks for taking the time to fill out a bug.
|
Thanks for taking the time to fill out a bug.
|
||||||
If you want real-time support, consider joining our Discord at https://discord.gg/r3sSKJJ instead.
|
If you want real-time support, consider joining our Discord at https://discord.gg/TvqYBrGXEm instead.
|
||||||
|
|
||||||
Please note that this form is for bugs only!
|
Please note that this form is for bugs only!
|
||||||
- type: input
|
- type: input
|
||||||
|
2
.github/ISSUE_TEMPLATE/config.yml
vendored
2
.github/ISSUE_TEMPLATE/config.yml
vendored
@ -5,4 +5,4 @@ contact_links:
|
|||||||
url: https://github.com/Rapptz/discord.py/discussions
|
url: https://github.com/Rapptz/discord.py/discussions
|
||||||
- name: Discord Server
|
- name: Discord Server
|
||||||
about: Use our official Discord server to ask for help and questions as well.
|
about: Use our official Discord server to ask for help and questions as well.
|
||||||
url: https://discord.gg/r3sSKJJ
|
url: https://discord.gg/TvqYBrGXEm
|
||||||
|
25
.github/workflows/black.yml
vendored
25
.github/workflows/black.yml
vendored
@ -1,25 +0,0 @@
|
|||||||
name: Lint
|
|
||||||
|
|
||||||
on: [push]
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
lint:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- name: checkout
|
|
||||||
uses: actions/checkout@v2
|
|
||||||
|
|
||||||
- name: Setup Python
|
|
||||||
uses: actions/setup-python@v1
|
|
||||||
with:
|
|
||||||
python-version: 3.8
|
|
||||||
|
|
||||||
- name: install black
|
|
||||||
run: pip install black
|
|
||||||
|
|
||||||
- name: run linter
|
|
||||||
uses: wearerequired/lint-action@v1
|
|
||||||
with:
|
|
||||||
black: true
|
|
||||||
black_args: ". --line-length 120"
|
|
||||||
auto_fix: true
|
|
38
.github/workflows/ci.yml
vendored
Normal file
38
.github/workflows/ci.yml
vendored
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
name: CI
|
||||||
|
|
||||||
|
on: [push, pull_request]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
pyright:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: checkout
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
|
||||||
|
- name: Setup Python
|
||||||
|
uses: actions/setup-python@v1
|
||||||
|
with:
|
||||||
|
python-version: 3.8
|
||||||
|
|
||||||
|
- name: Setup node.js (for pyright)
|
||||||
|
uses: actions/setup-node@v1
|
||||||
|
with:
|
||||||
|
node-version: "14"
|
||||||
|
|
||||||
|
- name: Run type checking
|
||||||
|
run: |
|
||||||
|
npm install -g pyright
|
||||||
|
pip install .
|
||||||
|
pyright --lib --verifytypes discord --ignoreexternal
|
||||||
|
|
||||||
|
black:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
|
||||||
|
- name: Run linter
|
||||||
|
uses: psf/black@stable
|
||||||
|
with:
|
||||||
|
options: "--line-length 120 --check"
|
||||||
|
src: "./discord"
|
1
.python-black
Normal file
1
.python-black
Normal file
@ -0,0 +1 @@
|
|||||||
|
|
@ -2,7 +2,7 @@ enhanced-discord.py
|
|||||||
===================
|
===================
|
||||||
|
|
||||||
.. image:: https://discord.com/api/guilds/514232441498763279/embed.png
|
.. image:: https://discord.com/api/guilds/514232441498763279/embed.png
|
||||||
:target: https://discord.gg/PYAfZzpsjG
|
:target: https://discord.gg/TvqYBrGXEm
|
||||||
:alt: Discord server invite
|
:alt: Discord server invite
|
||||||
.. image:: https://img.shields.io/pypi/v/enhanced-dpy.svg
|
.. image:: https://img.shields.io/pypi/v/enhanced-dpy.svg
|
||||||
:target: https://pypi.python.org/pypi/enhanced-dpy
|
:target: https://pypi.python.org/pypi/enhanced-dpy
|
||||||
@ -117,5 +117,5 @@ Links
|
|||||||
------
|
------
|
||||||
|
|
||||||
- `Documentation <https://enhanced-dpy.readthedocs.io/en/latest/index.html>`_
|
- `Documentation <https://enhanced-dpy.readthedocs.io/en/latest/index.html>`_
|
||||||
- `Official Discord Server <https://discord.gg/PYAfZzpsjG>`_
|
- `Official Discord Server <https://discord.gg/TvqYBrGXEm>`_
|
||||||
- `Discord API <https://discord.gg/discord-api>`_
|
- `Discord API <https://discord.gg/discord-api>`_
|
||||||
|
@ -398,16 +398,14 @@ class Embed:
|
|||||||
return EmbedProxy(getattr(self, "_image", {})) # type: ignore
|
return EmbedProxy(getattr(self, "_image", {})) # type: ignore
|
||||||
|
|
||||||
@image.setter
|
@image.setter
|
||||||
def image(self: E, url: Any):
|
def image(self, url: Any):
|
||||||
if url is EmptyEmbed:
|
if url is EmptyEmbed:
|
||||||
del self._image
|
del self.image
|
||||||
else:
|
else:
|
||||||
self._image = {
|
self._image = {"url": str(url)}
|
||||||
"url": str(url),
|
|
||||||
}
|
|
||||||
|
|
||||||
@image.deleter
|
@image.deleter
|
||||||
def image(self: E):
|
def image(self):
|
||||||
try:
|
try:
|
||||||
del self._image
|
del self._image
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
@ -429,7 +427,6 @@ class Embed:
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
self.image = url
|
self.image = url
|
||||||
|
|
||||||
return self
|
return self
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@ -448,13 +445,11 @@ class Embed:
|
|||||||
return EmbedProxy(getattr(self, "_thumbnail", {})) # type: ignore
|
return EmbedProxy(getattr(self, "_thumbnail", {})) # type: ignore
|
||||||
|
|
||||||
@thumbnail.setter
|
@thumbnail.setter
|
||||||
def thumbnail(self: E, url: Any):
|
def thumbnail(self, url: Any):
|
||||||
if url is EmptyEmbed:
|
if url is EmptyEmbed:
|
||||||
del self._thumbnail
|
del self.thumbnail
|
||||||
else:
|
else:
|
||||||
self._thumbnail = {
|
self._thumbnail = {"url": str(url)}
|
||||||
"url": str(url),
|
|
||||||
}
|
|
||||||
|
|
||||||
@thumbnail.deleter
|
@thumbnail.deleter
|
||||||
def thumbnail(self):
|
def thumbnail(self):
|
||||||
@ -463,7 +458,7 @@ class Embed:
|
|||||||
except AttributeError:
|
except AttributeError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def set_thumbnail(self: E, *, url: MaybeEmpty[Any]):
|
def set_thumbnail(self, *, url: MaybeEmpty[Any]):
|
||||||
"""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
|
||||||
@ -479,7 +474,6 @@ class Embed:
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
self.thumbnail = url
|
self.thumbnail = url
|
||||||
|
|
||||||
return self
|
return self
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
@ -330,6 +330,7 @@ class Command(_BaseCommand, Generic[CogT, P, T]):
|
|||||||
.. versionadded:: 2.0
|
.. versionadded:: 2.0
|
||||||
"""
|
"""
|
||||||
__original_kwargs__: Dict[str, Any]
|
__original_kwargs__: Dict[str, Any]
|
||||||
|
_max_concurrency: Optional[MaxConcurrency]
|
||||||
|
|
||||||
def __new__(cls: Type[CommandT], *args: Any, **kwargs: Any) -> CommandT:
|
def __new__(cls: Type[CommandT], *args: Any, **kwargs: Any) -> CommandT:
|
||||||
# if you're wondering why this is done, it's because we need to ensure
|
# if you're wondering why this is done, it's because we need to ensure
|
||||||
@ -392,17 +393,20 @@ class Command(_BaseCommand, Generic[CogT, P, T]):
|
|||||||
self.description: str = inspect.cleandoc(kwargs.get("description", ""))
|
self.description: str = inspect.cleandoc(kwargs.get("description", ""))
|
||||||
self.hidden: bool = kwargs.get("hidden", False)
|
self.hidden: bool = kwargs.get("hidden", False)
|
||||||
|
|
||||||
|
if hasattr(func, "__command_attrs__"):
|
||||||
|
command_attrs: Dict[str, Any] = func.__command_attrs__
|
||||||
|
else:
|
||||||
|
command_attrs = {}
|
||||||
|
|
||||||
try:
|
try:
|
||||||
checks = func.__commands_checks__
|
checks = func.__commands_checks__
|
||||||
checks.reverse()
|
checks.reverse()
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
checks = kwargs.get("checks", [])
|
checks = kwargs.get("checks", [])
|
||||||
|
|
||||||
self.checks: List[Check] = checks
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
cooldown = func.__commands_cooldown__
|
cooldown = command_attrs.pop("cooldown")
|
||||||
except AttributeError:
|
except KeyError:
|
||||||
cooldown = kwargs.get("cooldown")
|
cooldown = kwargs.get("cooldown")
|
||||||
|
|
||||||
if cooldown is None:
|
if cooldown is None:
|
||||||
@ -411,14 +415,10 @@ class Command(_BaseCommand, Generic[CogT, P, T]):
|
|||||||
buckets = cooldown
|
buckets = cooldown
|
||||||
else:
|
else:
|
||||||
raise TypeError("Cooldown must be a an instance of CooldownMapping or None.")
|
raise TypeError("Cooldown must be a an instance of CooldownMapping or None.")
|
||||||
|
|
||||||
|
self.checks: List[Check] = checks
|
||||||
self._buckets: CooldownMapping = buckets
|
self._buckets: CooldownMapping = buckets
|
||||||
|
self._max_concurrency = kwargs.get("max_concurrency")
|
||||||
try:
|
|
||||||
max_concurrency = func.__commands_max_concurrency__
|
|
||||||
except AttributeError:
|
|
||||||
max_concurrency = kwargs.get("max_concurrency")
|
|
||||||
|
|
||||||
self._max_concurrency: Optional[MaxConcurrency] = max_concurrency
|
|
||||||
|
|
||||||
self.require_var_positional: bool = kwargs.get("require_var_positional", False)
|
self.require_var_positional: bool = kwargs.get("require_var_positional", False)
|
||||||
self.ignore_extra: bool = kwargs.get("ignore_extra", True)
|
self.ignore_extra: bool = kwargs.get("ignore_extra", True)
|
||||||
@ -435,20 +435,23 @@ class Command(_BaseCommand, Generic[CogT, P, T]):
|
|||||||
|
|
||||||
self._before_invoke: Optional[Hook] = None
|
self._before_invoke: Optional[Hook] = None
|
||||||
try:
|
try:
|
||||||
before_invoke = func.__before_invoke__
|
before_invoke = command_attrs.pop("before_invoke")
|
||||||
except AttributeError:
|
except KeyError:
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
self.before_invoke(before_invoke)
|
self.before_invoke(before_invoke)
|
||||||
|
|
||||||
self._after_invoke: Optional[Hook] = None
|
self._after_invoke: Optional[Hook] = None
|
||||||
try:
|
try:
|
||||||
after_invoke = func.__after_invoke__
|
after_invoke = command_attrs.pop("after_invoke")
|
||||||
except AttributeError:
|
except KeyError:
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
self.after_invoke(after_invoke)
|
self.after_invoke(after_invoke)
|
||||||
|
|
||||||
|
# Handle user provided command attrs
|
||||||
|
self._update_attrs(**command_attrs)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def callback(
|
def callback(
|
||||||
self,
|
self,
|
||||||
@ -474,6 +477,10 @@ class Command(_BaseCommand, Generic[CogT, P, T]):
|
|||||||
|
|
||||||
self.params, self.option_descriptions = get_signature_parameters(function, globalns)
|
self.params, self.option_descriptions = get_signature_parameters(function, globalns)
|
||||||
|
|
||||||
|
def _update_attrs(self, **command_attrs: Any):
|
||||||
|
for key, value in command_attrs.items():
|
||||||
|
setattr(self, key, value)
|
||||||
|
|
||||||
def add_check(self, func: Check) -> None:
|
def add_check(self, func: Check) -> None:
|
||||||
"""Adds a check to the command.
|
"""Adds a check to the command.
|
||||||
|
|
||||||
@ -1829,7 +1836,7 @@ def group(
|
|||||||
return command(name=name, cls=cls, **attrs) # type: ignore
|
return command(name=name, cls=cls, **attrs) # type: ignore
|
||||||
|
|
||||||
|
|
||||||
def check(predicate: Check) -> Callable[[T], T]:
|
def check(predicate: Check, **command_attrs: Any) -> Callable[[T], T]:
|
||||||
r"""A decorator that adds a check to the :class:`.Command` or its
|
r"""A decorator that adds a check to the :class:`.Command` or its
|
||||||
subclasses. These checks could be accessed via :attr:`.Command.checks`.
|
subclasses. These checks could be accessed via :attr:`.Command.checks`.
|
||||||
|
|
||||||
@ -1898,16 +1905,22 @@ def check(predicate: Check) -> Callable[[T], T]:
|
|||||||
-----------
|
-----------
|
||||||
predicate: Callable[[:class:`Context`], :class:`bool`]
|
predicate: Callable[[:class:`Context`], :class:`bool`]
|
||||||
The predicate to check if the command should be invoked.
|
The predicate to check if the command should be invoked.
|
||||||
|
**command_attrs: Dict[:class:`str`, Any]
|
||||||
|
key: value pairs to be added to the command's attributes.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def decorator(func: Union[Command, CoroFunc]) -> Union[Command, CoroFunc]:
|
def decorator(func: Union[Command, CoroFunc]) -> Union[Command, CoroFunc]:
|
||||||
if isinstance(func, Command):
|
if isinstance(func, Command):
|
||||||
func.checks.append(predicate)
|
func.checks.append(predicate)
|
||||||
|
func._update_attrs(**command_attrs)
|
||||||
else:
|
else:
|
||||||
if not hasattr(func, "__commands_checks__"):
|
if not hasattr(func, "__commands_checks__"):
|
||||||
func.__commands_checks__ = []
|
func.__commands_checks__ = []
|
||||||
|
if not hasattr(func, "__command_attrs__"):
|
||||||
|
func.__command_attrs__ = {}
|
||||||
|
|
||||||
func.__commands_checks__.append(predicate)
|
func.__commands_checks__.append(predicate)
|
||||||
|
func.__command_attrs__.update(command_attrs)
|
||||||
|
|
||||||
return func
|
return func
|
||||||
|
|
||||||
@ -2080,7 +2093,7 @@ def has_any_role(*items: Union[int, str]) -> Callable[[T], T]:
|
|||||||
return True
|
return True
|
||||||
raise MissingAnyRole(list(items))
|
raise MissingAnyRole(list(items))
|
||||||
|
|
||||||
return check(predicate)
|
return check(predicate, required_roles=items)
|
||||||
|
|
||||||
|
|
||||||
def bot_has_role(item: int) -> Callable[[T], T]:
|
def bot_has_role(item: int) -> Callable[[T], T]:
|
||||||
@ -2110,7 +2123,7 @@ def bot_has_role(item: int) -> Callable[[T], T]:
|
|||||||
raise BotMissingRole(item)
|
raise BotMissingRole(item)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
return check(predicate)
|
return check(predicate, bot_required_role=item)
|
||||||
|
|
||||||
|
|
||||||
def bot_has_any_role(*items: int) -> Callable[[T], T]:
|
def bot_has_any_role(*items: int) -> Callable[[T], T]:
|
||||||
@ -2139,7 +2152,7 @@ def bot_has_any_role(*items: int) -> Callable[[T], T]:
|
|||||||
return True
|
return True
|
||||||
raise BotMissingAnyRole(list(items))
|
raise BotMissingAnyRole(list(items))
|
||||||
|
|
||||||
return check(predicate)
|
return check(predicate, bot_required_roles=items)
|
||||||
|
|
||||||
|
|
||||||
def has_permissions(**perms: bool) -> Callable[[T], T]:
|
def has_permissions(**perms: bool) -> Callable[[T], T]:
|
||||||
@ -2187,7 +2200,7 @@ def has_permissions(**perms: bool) -> Callable[[T], T]:
|
|||||||
|
|
||||||
raise MissingPermissions(missing)
|
raise MissingPermissions(missing)
|
||||||
|
|
||||||
return check(predicate)
|
return check(predicate, required_permissions=perms)
|
||||||
|
|
||||||
|
|
||||||
def bot_has_permissions(**perms: bool) -> Callable[[T], T]:
|
def bot_has_permissions(**perms: bool) -> Callable[[T], T]:
|
||||||
@ -2214,7 +2227,7 @@ def bot_has_permissions(**perms: bool) -> Callable[[T], T]:
|
|||||||
|
|
||||||
raise BotMissingPermissions(missing)
|
raise BotMissingPermissions(missing)
|
||||||
|
|
||||||
return check(predicate)
|
return check(predicate, bot_required_permissions=perms)
|
||||||
|
|
||||||
|
|
||||||
def has_guild_permissions(**perms: bool) -> Callable[[T], T]:
|
def has_guild_permissions(**perms: bool) -> Callable[[T], T]:
|
||||||
@ -2243,7 +2256,7 @@ def has_guild_permissions(**perms: bool) -> Callable[[T], T]:
|
|||||||
|
|
||||||
raise MissingPermissions(missing)
|
raise MissingPermissions(missing)
|
||||||
|
|
||||||
return check(predicate)
|
return check(predicate, required_guild_permissions=perms)
|
||||||
|
|
||||||
|
|
||||||
def bot_has_guild_permissions(**perms: bool) -> Callable[[T], T]:
|
def bot_has_guild_permissions(**perms: bool) -> Callable[[T], T]:
|
||||||
@ -2269,7 +2282,7 @@ def bot_has_guild_permissions(**perms: bool) -> Callable[[T], T]:
|
|||||||
|
|
||||||
raise BotMissingPermissions(missing)
|
raise BotMissingPermissions(missing)
|
||||||
|
|
||||||
return check(predicate)
|
return check(predicate, bot_required_guild_permissions=perms)
|
||||||
|
|
||||||
|
|
||||||
def dm_only() -> Callable[[T], T]:
|
def dm_only() -> Callable[[T], T]:
|
||||||
@ -2380,7 +2393,10 @@ def cooldown(
|
|||||||
if isinstance(func, Command):
|
if isinstance(func, Command):
|
||||||
func._buckets = CooldownMapping(Cooldown(rate, per), type)
|
func._buckets = CooldownMapping(Cooldown(rate, per), type)
|
||||||
else:
|
else:
|
||||||
func.__commands_cooldown__ = CooldownMapping(Cooldown(rate, per), type)
|
if not hasattr(func, "__command_attrs__"):
|
||||||
|
func.__command_attrs__ = {}
|
||||||
|
|
||||||
|
func.__command_attrs__["cooldown"] = CooldownMapping(Cooldown(rate, per), type)
|
||||||
return func
|
return func
|
||||||
|
|
||||||
return decorator # type: ignore
|
return decorator # type: ignore
|
||||||
@ -2424,7 +2440,10 @@ def dynamic_cooldown(
|
|||||||
if isinstance(func, Command):
|
if isinstance(func, Command):
|
||||||
func._buckets = DynamicCooldownMapping(cooldown, type)
|
func._buckets = DynamicCooldownMapping(cooldown, type)
|
||||||
else:
|
else:
|
||||||
func.__commands_cooldown__ = DynamicCooldownMapping(cooldown, type)
|
if not hasattr(func, "__command_attrs__"):
|
||||||
|
func.__command_attrs__ = {}
|
||||||
|
|
||||||
|
func.__command_attrs__["cooldown"] = DynamicCooldownMapping(cooldown, type)
|
||||||
return func
|
return func
|
||||||
|
|
||||||
return decorator # type: ignore
|
return decorator # type: ignore
|
||||||
@ -2459,7 +2478,10 @@ def max_concurrency(number: int, per: BucketType = BucketType.default, *, wait:
|
|||||||
if isinstance(func, Command):
|
if isinstance(func, Command):
|
||||||
func._max_concurrency = value
|
func._max_concurrency = value
|
||||||
else:
|
else:
|
||||||
func.__commands_max_concurrency__ = value
|
if not hasattr(func, "__command_attrs__"):
|
||||||
|
func.__command_attrs__ = {}
|
||||||
|
|
||||||
|
func.__command_attrs__["_max_concurrency"] = value
|
||||||
return func
|
return func
|
||||||
|
|
||||||
return decorator # type: ignore
|
return decorator # type: ignore
|
||||||
@ -2508,7 +2530,10 @@ def before_invoke(coro) -> Callable[[T], T]:
|
|||||||
if isinstance(func, Command):
|
if isinstance(func, Command):
|
||||||
func.before_invoke(coro)
|
func.before_invoke(coro)
|
||||||
else:
|
else:
|
||||||
func.__before_invoke__ = coro
|
if not hasattr(func, "__command_attrs__"):
|
||||||
|
func.__command_attrs__ = {}
|
||||||
|
|
||||||
|
func.__command_attrs__["before_invoke"] = coro
|
||||||
return func
|
return func
|
||||||
|
|
||||||
return decorator # type: ignore
|
return decorator # type: ignore
|
||||||
@ -2527,7 +2552,7 @@ def after_invoke(coro) -> Callable[[T], T]:
|
|||||||
if isinstance(func, Command):
|
if isinstance(func, Command):
|
||||||
func.after_invoke(coro)
|
func.after_invoke(coro)
|
||||||
else:
|
else:
|
||||||
func.__after_invoke__ = coro
|
func.__command_attrs__["after_invoke"] = coro
|
||||||
return func
|
return func
|
||||||
|
|
||||||
return decorator # type: ignore
|
return decorator # type: ignore
|
||||||
|
@ -169,9 +169,14 @@ class Attachment(Hashable):
|
|||||||
The attachment's `media type <https://en.wikipedia.org/wiki/Media_type>`_
|
The attachment's `media type <https://en.wikipedia.org/wiki/Media_type>`_
|
||||||
|
|
||||||
.. versionadded:: 1.7
|
.. versionadded:: 1.7
|
||||||
|
ephemeral: Optional[:class:`bool`]
|
||||||
|
If the attachment is ephemeral. Ephemeral attachments are temporary and
|
||||||
|
will automatically be removed after a set period of time.
|
||||||
|
|
||||||
|
.. versionadded:: 2.0
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__slots__ = ("id", "size", "height", "width", "filename", "url", "proxy_url", "_http", "content_type")
|
__slots__ = ("id", "size", "height", "width", "filename", "url", "proxy_url", "ephemeral", "_http", "content_type")
|
||||||
|
|
||||||
def __init__(self, *, data: AttachmentPayload, state: ConnectionState):
|
def __init__(self, *, data: AttachmentPayload, state: ConnectionState):
|
||||||
self.id: int = int(data["id"])
|
self.id: int = int(data["id"])
|
||||||
@ -183,6 +188,7 @@ class Attachment(Hashable):
|
|||||||
self.proxy_url: str = data.get("proxy_url")
|
self.proxy_url: str = data.get("proxy_url")
|
||||||
self._http = state.http
|
self._http = state.http
|
||||||
self.content_type: Optional[str] = data.get("content_type")
|
self.content_type: Optional[str] = data.get("content_type")
|
||||||
|
self.ephemeral: Optional[bool] = data.get("ephemeral")
|
||||||
|
|
||||||
def is_spoiler(self) -> bool:
|
def is_spoiler(self) -> bool:
|
||||||
""":class:`bool`: Whether this attachment contains a spoiler."""
|
""":class:`bool`: Whether this attachment contains a spoiler."""
|
||||||
|
@ -53,6 +53,7 @@ class _AttachmentOptional(TypedDict, total=False):
|
|||||||
height: Optional[int]
|
height: Optional[int]
|
||||||
width: Optional[int]
|
width: Optional[int]
|
||||||
content_type: str
|
content_type: str
|
||||||
|
ephemeral: bool
|
||||||
spoiler: bool
|
spoiler: bool
|
||||||
|
|
||||||
|
|
||||||
|
@ -80,7 +80,7 @@ class BaseUser(_UserTag):
|
|||||||
_state: ConnectionState
|
_state: ConnectionState
|
||||||
_avatar: Optional[str]
|
_avatar: Optional[str]
|
||||||
_banner: Optional[str]
|
_banner: Optional[str]
|
||||||
_accent_colour: Optional[str]
|
_accent_colour: Optional[int]
|
||||||
_public_flags: int
|
_public_flags: int
|
||||||
|
|
||||||
def __init__(self, *, state: ConnectionState, data: UserPayload) -> None:
|
def __init__(self, *, state: ConnectionState, data: UserPayload) -> None:
|
||||||
|
@ -27,7 +27,7 @@ async def userinfo(ctx: commands.Context, user: discord.User):
|
|||||||
# and can do the following:
|
# and can do the following:
|
||||||
user_id = user.id
|
user_id = user.id
|
||||||
username = user.name
|
username = user.name
|
||||||
avatar = user.avatar.url
|
avatar = user.display_avatar.url
|
||||||
await ctx.send(f"User found: {user_id} -- {username}\n{avatar}")
|
await ctx.send(f"User found: {user_id} -- {username}\n{avatar}")
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user