diff options
| author | Rapptz <[email protected]> | 2018-06-10 18:09:14 -0400 |
|---|---|---|
| committer | Rapptz <[email protected]> | 2018-06-10 18:10:00 -0400 |
| commit | f25091efe1281aebe70189c61f9cac405b21a72f (patch) | |
| tree | d0d13dad1a89de9f45845a36ea475098b7a0b494 /discord/client.py | |
| parent | Add Message.jump_to_url (diff) | |
| download | discord.py-f25091efe1281aebe70189c61f9cac405b21a72f.tar.xz discord.py-f25091efe1281aebe70189c61f9cac405b21a72f.zip | |
Drop support for Python 3.4 and make minimum version 3.5.2.
Diffstat (limited to 'discord/client.py')
| -rw-r--r-- | discord/client.py | 128 |
1 files changed, 53 insertions, 75 deletions
diff --git a/discord/client.py b/discord/client.py index 0434d1e2..a46f1637 100644 --- a/discord/client.py +++ b/discord/client.py @@ -48,7 +48,6 @@ import sys, re import signal from collections import namedtuple -PY35 = sys.version_info >= (3, 5) log = logging.getLogger(__name__) AppInfo = namedtuple('AppInfo', 'id name description icon owner') @@ -139,12 +138,10 @@ class Client: # internals - @asyncio.coroutine - def _syncer(self, guilds): - yield from self.ws.request_sync(guilds) + async def _syncer(self, guilds): + await self.ws.request_sync(guilds) - @asyncio.coroutine - def _chunker(self, guild): + async def _chunker(self, guild): try: guild_id = guild.id except AttributeError: @@ -159,7 +156,7 @@ class Client: } } - yield from self.ws.send_as_json(payload) + await self.ws.send_as_json(payload) def handle_ready(self): self._ready.set() @@ -218,15 +215,14 @@ class Client: """:obj:`bool`: Specifies if the client's internal cache is ready for use.""" return self._ready.is_set() - @asyncio.coroutine - def _run_event(self, coro, event_name, *args, **kwargs): + async def _run_event(self, coro, event_name, *args, **kwargs): try: - yield from coro(*args, **kwargs) + await coro(*args, **kwargs) except asyncio.CancelledError: pass except Exception: try: - yield from self.on_error(event_name, *args, **kwargs) + await self.on_error(event_name, *args, **kwargs) except asyncio.CancelledError: pass @@ -276,10 +272,9 @@ class Client: except AttributeError: pass else: - compat.create_task(self._run_event(coro, method, *args, **kwargs), loop=self.loop) + asyncio.ensure_future(self._run_event(coro, method, *args, **kwargs), loop=self.loop) - @asyncio.coroutine - def on_error(self, event_method, *args, **kwargs): + async def on_error(self, event_method, *args, **kwargs): """|coro| The default error handler provided by the client. @@ -291,8 +286,7 @@ class Client: print('Ignoring exception in {}'.format(event_method), file=sys.stderr) traceback.print_exc() - @asyncio.coroutine - def request_offline_members(self, *guilds): + async def request_offline_members(self, *guilds): """|coro| Requests previously offline members from the guild to be filled up @@ -318,12 +312,11 @@ class Client: if any(not g.large or g.unavailable for g in guilds): raise InvalidArgument('An unavailable or non-large guild was passed.') - yield from self._connection.request_offline_members(guilds) + await self._connection.request_offline_members(guilds) # login state management - @asyncio.coroutine - def login(self, token, *, bot=True): + async def login(self, token, *, bot=True): """|coro| Logs in the client with the specified credentials. @@ -350,34 +343,31 @@ class Client: """ log.info('logging in using static token') - yield from self.http.static_login(token, bot=bot) + await self.http.static_login(token, bot=bot) self._connection.is_bot = bot - @asyncio.coroutine - def logout(self): + async def logout(self): """|coro| Logs out of Discord and closes all connections. """ - yield from self.close() + await self.close() - @asyncio.coroutine - def _connect(self): + async def _connect(self): coro = DiscordWebSocket.from_client(self, shard_id=self.shard_id) - self.ws = yield from asyncio.wait_for(coro, timeout=180.0, loop=self.loop) + self.ws = await asyncio.wait_for(coro, timeout=180.0, loop=self.loop) while True: try: - yield from self.ws.poll_event() + await self.ws.poll_event() except ResumeWebSocket as e: log.info('Got a request to RESUME the websocket.') coro = DiscordWebSocket.from_client(self, shard_id=self.shard_id, session=self.ws.session_id, sequence=self.ws.sequence, resume=True) - self.ws = yield from asyncio.wait_for(coro, timeout=180.0, loop=self.loop) + self.ws = await asyncio.wait_for(coro, timeout=180.0, loop=self.loop) - @asyncio.coroutine - def connect(self, *, reconnect=True): + async def connect(self, *, reconnect=True): """|coro| Creates a websocket connection and lets the websocket listen @@ -405,7 +395,7 @@ class Client: backoff = ExponentialBackoff() while not self.is_closed(): try: - yield from self._connect() + await self._connect() except (OSError, HTTPException, GatewayNotFound, @@ -416,7 +406,7 @@ class Client: websockets.WebSocketProtocolError) as e: if not reconnect: - yield from self.close() + await self.close() if isinstance(e, ConnectionClosed) and e.code == 1000: # clean close, don't re-raise this return @@ -431,15 +421,14 @@ class Client: # regardless and rely on is_closed instead if isinstance(e, ConnectionClosed): if e.code != 1000: - yield from self.close() + await self.close() raise retry = backoff.delay() log.exception("Attempting a reconnect in %.2fs", retry) - yield from asyncio.sleep(retry, loop=self.loop) + await asyncio.sleep(retry, loop=self.loop) - @asyncio.coroutine - def close(self): + async def close(self): """|coro| Closes the connection to discord. @@ -451,16 +440,16 @@ class Client: for voice in self.voice_clients: try: - yield from voice.disconnect() + await voice.disconnect() except: # if an error happens during disconnects, disregard it. pass if self.ws is not None and self.ws.open: - yield from self.ws.close() + await self.ws.close() - yield from self.http.close() + await self.http.close() self._ready.clear() def clear(self): @@ -475,8 +464,7 @@ class Client: self._connection.clear() self.http.recreate() - @asyncio.coroutine - def start(self, *args, **kwargs): + async def start(self, *args, **kwargs): """|coro| A shorthand coroutine for :meth:`login` + :meth:`connect`. @@ -484,8 +472,8 @@ class Client: bot = kwargs.pop('bot', True) reconnect = kwargs.pop('reconnect', True) - yield from self.login(*args, bot=bot) - yield from self.connect(reconnect=reconnect) + await self.login(*args, bot=bot) + await self.connect(reconnect=reconnect) def _do_cleanup(self): log.info('Cleaning up event loop.') @@ -493,7 +481,7 @@ class Client: if loop.is_closed(): return # we're already cleaning up - task = compat.create_task(self.close(), loop=loop) + task = asyncio.ensure_future(self.close(), loop=loop) def _silence_gathered(fut): try: @@ -558,7 +546,7 @@ class Client: loop.add_signal_handler(signal.SIGINT, self._do_cleanup) loop.add_signal_handler(signal.SIGTERM, self._do_cleanup) - task = compat.create_task(self.start(*args, **kwargs), loop=loop) + task = asyncio.ensure_future(self.start(*args, **kwargs), loop=loop) def stop_loop_on_finish(fut): loop.stop() @@ -661,13 +649,12 @@ class Client: # listeners/waiters - @asyncio.coroutine - def wait_until_ready(self): + async def wait_until_ready(self): """|coro| Waits until the client's internal cache is all ready. """ - yield from self._ready.wait() + await self._ready.wait() def wait_for(self, event, *, check=None, timeout=None): """|coro| @@ -751,7 +738,7 @@ class Client: :ref:`event reference <discord-api-events>`. """ - future = compat.create_future(self.loop) + future = self.loop.create_future() if check is None: def _check(*args): return True @@ -782,8 +769,7 @@ class Client: Using the basic :meth:`event` decorator: :: @client.event - @asyncio.coroutine - def on_ready(): + async def on_ready(): print('Ready!') Saving characters by using the :meth:`async_event` decorator: :: @@ -808,8 +794,7 @@ class Client: return self.event(coro) - @asyncio.coroutine - def change_presence(self, *, activity=None, status=None, afk=False): + async def change_presence(self, *, activity=None, status=None, afk=False): """|coro| Changes the client's presence. @@ -851,7 +836,7 @@ class Client: status_enum = status status = str(status) - yield from self.ws.change_presence(activity=activity, status=status, afk=afk) + await self.ws.change_presence(activity=activity, status=status, afk=afk) for guild in self._connection.guilds: me = guild.me @@ -863,8 +848,7 @@ class Client: # Guild stuff - @asyncio.coroutine - def create_guild(self, name, region=None, icon=None): + async def create_guild(self, name, region=None, icon=None): """|coro| Creates a :class:`Guild`. @@ -903,13 +887,12 @@ class Client: else: region = region.value - data = yield from self.http.create_guild(name, region, icon) + data = await self.http.create_guild(name, region, icon) return Guild(data=data, state=self._connection) # Invite management - @asyncio.coroutine - def get_invite(self, url): + async def get_invite(self, url): """|coro| Gets an :class:`Invite` from a discord.gg URL or ID. @@ -939,11 +922,10 @@ class Client: """ invite_id = self._resolve_invite(url) - data = yield from self.http.get_invite(invite_id) + data = await self.http.get_invite(invite_id) return Invite.from_incomplete(state=self._connection, data=data) - @asyncio.coroutine - def delete_invite(self, invite): + async def delete_invite(self, invite): """|coro| Revokes an :class:`Invite`, URL, or ID to an invite. @@ -967,12 +949,11 @@ class Client: """ invite_id = self._resolve_invite(invite) - yield from self.http.delete_invite(invite_id) + await self.http.delete_invite(invite_id) # Miscellaneous stuff - @asyncio.coroutine - def application_info(self): + async def application_info(self): """|coro| Retrieve's the bot's application information. @@ -987,13 +968,12 @@ class Client: HTTPException Retrieving the information failed somehow. """ - data = yield from self.http.application_info() + data = await self.http.application_info() return AppInfo(id=int(data['id']), name=data['name'], description=data['description'], icon=data['icon'], owner=User(state=self._connection, data=data['owner'])) - @asyncio.coroutine - def get_user_info(self, user_id): + async def get_user_info(self, user_id): """|coro| Retrieves a :class:`User` based on their ID. This can only @@ -1018,11 +998,10 @@ class Client: HTTPException Fetching the user failed. """ - data = yield from self.http.get_user_info(user_id) + data = await self.http.get_user_info(user_id) return User(state=self._connection, data=data) - @asyncio.coroutine - def get_user_profile(self, user_id): + async def get_user_profile(self, user_id): """|coro| Gets an arbitrary user's profile. This can only be used by non-bot accounts. @@ -1046,7 +1025,7 @@ class Client: """ state = self._connection - data = yield from self.http.get_user_profile(user_id) + data = await self.http.get_user_profile(user_id) def transform(d): return state._get_guild(int(d['id'])) @@ -1060,8 +1039,7 @@ class Client: user=User(data=user, state=state), connected_accounts=data['connected_accounts']) - @asyncio.coroutine - def get_webhook_info(self, webhook_id): + async def get_webhook_info(self, webhook_id): """|coro| Retrieves a :class:`Webhook` with the specified ID. @@ -1080,5 +1058,5 @@ class Client: :class:`Webhook` The webhook you requested. """ - data = yield from self.http.get_webhook(webhook_id) + data = await self.http.get_webhook(webhook_id) return Webhook.from_state(data, state=self._connection) |