Skip to content

Commit 20198ad

Browse files
authored
quiq-fixed Object have no attribute send
Should Type `Object` have no attribute `send` quickly fixed
1 parent 073507e commit 20198ad

File tree

7 files changed

+226
-67
lines changed

7 files changed

+226
-67
lines changed

discord/abc.py

+4-5
Original file line numberDiff line numberDiff line change
@@ -1070,17 +1070,16 @@ async def send(self, content=None, *, tts=False, embed=None, embeds=None, compon
10701070
if file is not None and files is not None:
10711071
raise InvalidArgument('cannot pass both file and files parameter to send()')
10721072

1073-
is_interaction_response = kwargs.pop('__is_interaction_response', None)
1073+
is_interaction_response = kwargs.pop('__is_interaction_response', False)
10741074
deferred = kwargs.pop('__deferred', False)
10751075
use_webhook = kwargs.pop('__use_webhook', False)
10761076
interaction_id = kwargs.pop('__interaction_id', None)
10771077
interaction_token = kwargs.pop('__interaction_token', None)
10781078
application_id = kwargs.pop('__application_id', None)
10791079
followup = kwargs.pop('followup', False)
1080-
if is_interaction_response is False or None:
1081-
hidden = None
1082-
if hidden is True and file or files:
1083-
raise AttributeError('An ephemeral(hidden) Message could not contain file(s)')
1080+
if is_interaction_response:
1081+
if hidden and file or files:
1082+
raise AttributeError('An ephemeral(hidden) Message could not contain file(s)')
10841083
if file is not None:
10851084
if not isinstance(file, File):
10861085
raise InvalidArgument('file parameter must be File')

discord/channel.py

+82-1
Original file line numberDiff line numberDiff line change
@@ -26,15 +26,35 @@
2626

2727
import time
2828
import asyncio
29-
29+
from typing import (
30+
Any,
31+
Callable,
32+
Dict,
33+
Iterable,
34+
List,
35+
Mapping,
36+
Optional,
37+
TYPE_CHECKING,
38+
Tuple,
39+
Type,
40+
TypeVar,
41+
Union,
42+
overload,
43+
)
3044
import discord.abc
3145
from .permissions import Permissions
3246
from .enums import ChannelType, try_enum, VoiceRegion
3347
from .mixins import Hashable
3448
from . import utils
49+
from .object import Object
3550
from .asset import Asset
3651
from .errors import ClientException, NoMoreItems, InvalidArgument
3752

53+
if TYPE_CHECKING:
54+
from .state import ConnectionState
55+
from .message import Message, PartialMessage
56+
57+
3858
__all__ = (
3959
'TextChannel',
4060
'VoiceChannel',
@@ -1224,6 +1244,16 @@ def __str__(self):
12241244
def __repr__(self):
12251245
return '<DMChannel id={0.id} recipient={0.recipient!r}>'.format(self)
12261246

1247+
@classmethod
1248+
def _from_message(cls, state, channel_id: int):
1249+
self = cls.__new__(cls)
1250+
self._state = state
1251+
self.id = channel_id
1252+
self.recipient = None
1253+
# state.user won't be None here
1254+
self.me = state.user # type: ignore
1255+
return self
1256+
12271257
@property
12281258
def type(self):
12291259
""":class:`ChannelType`: The channel's Discord type."""
@@ -1545,6 +1575,57 @@ async def leave(self):
15451575

15461576
await self._state.http.leave_group(self.id)
15471577

1578+
1579+
class PartialMessageable(discord.abc.Messageable, Hashable):
1580+
"""Represents a partial messageable to aid with working messageable channels when
1581+
only a channel ID are present.
1582+
The only way to construct this class is through :meth:`Client.get_partial_messageable`.
1583+
Note that this class is trimmed down and has no rich attributes.
1584+
.. versionadded:: 2.0
1585+
.. container:: operations
1586+
.. describe:: x == y
1587+
Checks if two partial messageables are equal.
1588+
.. describe:: x != y
1589+
Checks if two partial messageables are not equal.
1590+
.. describe:: hash(x)
1591+
Returns the partial messageable's hash.
1592+
Attributes
1593+
-----------
1594+
id: :class:`int`
1595+
The channel ID associated with this partial messageable.
1596+
type: Optional[:class:`ChannelType`]
1597+
The channel type associated with this partial messageable, if given.
1598+
"""
1599+
1600+
def __init__(self, state: 'ConnectionState', id: int, type: Optional[ChannelType] = None):
1601+
self._state: ConnectionState = state
1602+
self._channel: Object = Object(id=id)
1603+
self.id: int = id
1604+
self.type: Optional[ChannelType] = type
1605+
1606+
async def _get_channel(self) -> Object:
1607+
return self._channel
1608+
1609+
def get_partial_message(self, message_id: int, /):
1610+
"""Creates a :class:`PartialMessage` from the message ID.
1611+
This is useful if you want to work with a message and only have its ID without
1612+
doing an unnecessary API call.
1613+
Parameters
1614+
------------
1615+
message_id: :class:`int`
1616+
The message ID to create a partial message for.
1617+
Returns
1618+
---------
1619+
:class:`PartialMessage`
1620+
The partial message.
1621+
"""
1622+
1623+
from .message import PartialMessage
1624+
1625+
return PartialMessage(channel=self, id=message_id)
1626+
1627+
1628+
15481629
def _channel_factory(channel_type):
15491630
value = try_enum(ChannelType, channel_type)
15501631
if value is ChannelType.text:

0 commit comments

Comments
 (0)