conflict fixes

This commit is contained in:
iDutchy
2021-04-07 18:27:34 -05:00
94 changed files with 4512 additions and 3018 deletions

View File

@@ -1,9 +1,7 @@
# -*- coding: utf-8 -*-
"""
The MIT License (MIT)
Copyright (c) 2015-2020 Rapptz
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"),
@@ -34,7 +32,7 @@ import re
import aiohttp
from .user import User, Profile
from .user import User
from .invite import Invite
from .template import Template
from .widget import Widget
@@ -57,16 +55,14 @@ from .iterators import GuildIterator
from .appinfo import AppInfo
from .colour import Color, Colour
__all__ = (
'Client',
)
log = logging.getLogger(__name__)
def _cancel_tasks(loop):
try:
task_retriever = asyncio.Task.all_tasks
except AttributeError:
# future proofing for 3.9 I guess
task_retriever = asyncio.all_tasks
tasks = {t for t in task_retriever(loop=loop) if not t.done()}
tasks = {t for t in asyncio.all_tasks(loop=loop) if not t.done()}
if not tasks:
return
@@ -91,28 +87,11 @@ def _cancel_tasks(loop):
def _cleanup_loop(loop):
try:
_cancel_tasks(loop)
if sys.version_info >= (3, 6):
loop.run_until_complete(loop.shutdown_asyncgens())
loop.run_until_complete(loop.shutdown_asyncgens())
finally:
log.info('Closing the event loop.')
loop.close()
class _ClientEventTask(asyncio.Task):
def __init__(self, original_coro, event_name, coro, *, loop):
super().__init__(coro, loop=loop)
self.__event_name = event_name
self.__original_coro = original_coro
def __repr__(self):
info = [
('state', self._state.lower()),
('event', self.__event_name),
('coro', repr(self.__original_coro)),
]
if self._exception is not None:
info.append(('exception', repr(self._exception)))
return '<ClientEventTask {}>'.format(' '.join('%s=%s' % t for t in info))
class Client:
r"""Represents a client connection that connects to Discord.
This class is used to interact with the Discord WebSocket and API.
@@ -141,6 +120,8 @@ class Client:
Integer starting at ``0`` and less than :attr:`.shard_count`.
shard_count: Optional[:class:`int`]
The total number of shards.
application_id: :class:`int`
The client's application ID.
intents: :class:`Intents`
The intents that you want to enable for the session. This is a way of
disabling and enabling certain gateway events from triggering and being sent.
@@ -344,10 +325,7 @@ class Client:
def _get_state(self, **options):
return ConnectionState(dispatch=self.dispatch, handlers=self._handlers,
hooks=self._hooks, syncer=self._syncer, http=self.http, loop=self.loop, **options)
async def _syncer(self, guilds):
await self.ws.request_sync(guilds)
hooks=self._hooks, http=self.http, loop=self.loop, **options)
def _handle_ready(self):
self._ready.set()
@@ -415,6 +393,16 @@ class Client:
"""
return self._connection.voice_clients
@property
def application_id(self):
"""Optional[:class:`int`]: The client's application ID.
If this is not passed via ``__init__`` then this is retrieved
through the gateway when an event contains the data. Usually
after :func:`on_connect` is called.
"""
return self._connection.application_id
def is_ready(self):
""":class:`bool`: Specifies if the client's internal cache is ready for use."""
return self._ready.is_set()
@@ -433,7 +421,7 @@ class Client:
def _schedule_event(self, coro, event_name, *args, **kwargs):
wrapped = self._run_event(coro, event_name, *args, **kwargs)
# Schedules the task
return _ClientEventTask(original_coro=coro, event_name=event_name, coro=wrapped, loop=self.loop)
return asyncio.create_task(wrapped, name=f'discord.py: {event_name}')
def dispatch(self, event, *args, **kwargs):
log.debug('Dispatching event %s', event)
@@ -484,43 +472,9 @@ class Client:
overridden to have a different implementation.
Check :func:`~discord.on_error` for more details.
"""
print('Ignoring exception in {}'.format(event_method), file=sys.stderr)
print(f'Ignoring exception in {event_method}', file=sys.stderr)
traceback.print_exc()
@utils.deprecated('Guild.chunk')
async def request_offline_members(self, *guilds):
r"""|coro|
Requests previously offline members from the guild to be filled up
into the :attr:`.Guild.members` cache. This function is usually not
called. It should only be used if you have the ``fetch_offline_members``
parameter set to ``False``.
When the client logs on and connects to the websocket, Discord does
not provide the library with offline members if the number of members
in the guild is larger than 250. You can check if a guild is large
if :attr:`.Guild.large` is ``True``.
.. warning::
This method is deprecated. Use :meth:`Guild.chunk` instead.
Parameters
-----------
\*guilds: :class:`.Guild`
An argument list of guilds to request offline members for.
Raises
-------
:exc:`.InvalidArgument`
If any guild is unavailable in the collection.
"""
if any(g.unavailable for g in guilds):
raise InvalidArgument('An unavailable guild was passed.')
for guild in guilds:
await self._connection.chunk_guild(guild)
# hooks
async def _call_before_identify_hook(self, shard_id, *, initial=False):
@@ -553,7 +507,7 @@ class Client:
# login state management
async def login(self, token, *, bot=True):
async def login(self, token):
"""|coro|
Logs in the client with the specified credentials.
@@ -572,9 +526,6 @@ class Client:
token: :class:`str`
The authentication token. Do not prefix this token with
anything as the library will do it for you.
bot: :class:`bool`
Keyword argument that specifies if the account logging on is a bot
token or not.
Raises
------
@@ -587,21 +538,7 @@ class Client:
"""
log.info('logging in using static token')
await self.http.static_login(token.strip(), bot=bot)
self._connection.is_bot = bot
async def logout(self):
"""|coro|
Logs out of Discord and closes all connections.
.. note::
This is just an alias to :meth:`close`. If you want
to do extraneous cleanup when subclassing, it is suggested
to override :meth:`close` instead.
"""
await self.close()
await self.http.static_login(token.strip())
async def connect(self, *, reconnect=True):
"""|coro|
@@ -722,7 +659,7 @@ class Client:
self._connection.clear()
self.http.recreate()
async def start(self, *args, **kwargs):
async def start(self, token, *, reconnect=True):
"""|coro|
A shorthand coroutine for :meth:`login` + :meth:`connect`.
@@ -732,13 +669,7 @@ class Client:
TypeError
An unexpected keyword argument was received.
"""
bot = kwargs.pop('bot', True)
reconnect = kwargs.pop('reconnect', True)
if kwargs:
raise TypeError("unexpected keyword argument(s) %s" % list(kwargs.keys()))
await self.login(*args, bot=bot)
await self.login(token)
await self.connect(reconnect=reconnect)
def run(self, *args, **kwargs):
@@ -754,7 +685,7 @@ class Client:
try:
loop.run_until_complete(start(*args, **kwargs))
except KeyboardInterrupt:
loop.run_until_complete(logout())
loop.run_until_complete(close())
# cancel all tasks lingering
finally:
loop.close()
@@ -833,12 +764,10 @@ class Client:
@allowed_mentions.setter
def allowed_mentions(self, value):
if value is None:
self._connection.allowed_mentions = value
elif isinstance(value, AllowedMentions):
if value is None or isinstance(value, AllowedMentions):
self._connection.allowed_mentions = value
else:
raise TypeError('allowed_mentions must be AllowedMentions not {0.__class__!r}'.format(value))
raise TypeError(f'allowed_mentions must be AllowedMentions not {value.__class__!r}')
@property
def intents(self):
@@ -937,8 +866,7 @@ class Client:
"""
for guild in self.guilds:
for channel in guild.channels:
yield channel
yield from guild.channels
def get_all_members(self):
"""Returns a generator with every :class:`.Member` the client can see.
@@ -955,8 +883,7 @@ class Client:
A member the client can see.
"""
for guild in self.guilds:
for member in guild.members:
yield member
yield from guild.members
# listeners/waiters
@@ -1154,9 +1081,7 @@ class Client:
# Guild stuff
def fetch_guilds(self, *, limit=100, before=None, after=None):
"""|coro|
Retrieves an :class:`.AsyncIterator` that enables receiving your guilds.
"""Retrieves an :class:`.AsyncIterator` that enables receiving your guilds.
.. note::
@@ -1191,10 +1116,12 @@ class Client:
Defaults to ``100``.
before: Union[:class:`.abc.Snowflake`, :class:`datetime.datetime`]
Retrieves guilds before this date or object.
If a date is provided it must be a timezone-naive datetime representing UTC time.
If a datetime is provided, it is recommended to use a UTC aware datetime.
If the datetime is naive, it is assumed to be local time.
after: Union[:class:`.abc.Snowflake`, :class:`datetime.datetime`]
Retrieve guilds after this date or object.
If a date is provided it must be a timezone-naive datetime representing UTC time.
If a datetime is provided, it is recommended to use a UTC aware datetime.
If the datetime is naive, it is assumed to be local time.
Raises
------
@@ -1306,15 +1233,13 @@ class Client:
if icon is not None:
icon = utils._bytes_to_base64_data(icon)
if region is None:
region = VoiceRegion.us_west.value
else:
region = region.value
region = region or VoiceRegion.us_west
region_value = region.value
if code:
data = await self.http.create_from_template(code, name, region, icon)
data = await self.http.create_from_template(code, name, region_value, icon)
else:
data = await self.http.create_guild(name, region, icon)
data = await self.http.create_guild(name, region_value, icon)
return Guild(data=data, state=self._connection)
# Invite management
@@ -1502,48 +1427,6 @@ class Client:
data = await self.http.get_user(user_id)
return User(state=self._connection, data=data)
async def fetch_user_profile(self, user_id):
"""|coro|
Gets an arbitrary user's profile.
.. note::
This can only be used by non-bot accounts.
Parameters
------------
user_id: :class:`int`
The ID of the user to fetch their profile for.
Raises
-------
:exc:`.Forbidden`
Not allowed to fetch profiles.
:exc:`.HTTPException`
Fetching the profile failed.
Returns
--------
:class:`.Profile`
The profile of the user.
"""
state = self._connection
data = await self.http.get_user_profile(user_id)
def transform(d):
return state._get_guild(int(d['id']))
since = data.get('premium_since')
mutual_guilds = list(filter(None, map(transform, data.get('mutual_guilds', []))))
user = data['user']
return Profile(flags=user.get('flags', 0),
premium_since=utils.parse_time(since),
mutual_guilds=mutual_guilds,
user=User(data=user, state=state),
connected_accounts=data['connected_accounts'])
async def fetch_channel(self, channel_id):
"""|coro|