qwertyquerty / pypresence

A complete Discord IPC and Rich Presence wrapper library in Python!
https://qwertyquerty.github.io/pypresence/html/index.html
MIT License
652 stars 76 forks source link

AioClient doesn't await on_event #196

Closed aw-was-here closed 7 months ago

aw-was-here commented 1 year ago

Running a simple test of AioClient reveals that it isn't properly await'ing everything:


import asyncio
import pypresence

CLIENT_ID='your client id here'

async def main():
    client = pypresence.AioClient(CLIENT_ID)
    await client.start()
    while True:
        await client.set_activity(state='Testing pypresence AioClient')
        await asyncio.sleep(15)

if __name__ == '__main__':
    asyncio.run(main())

Error during run is:

/usr/lib/python3.10/asyncio/streams.py:266: RuntimeWarning: coroutine 'AioClient.on_event' was never awaited
  reader.feed_data(data)
RuntimeWarning: Enable tracemalloc to get the object allocation traceback
TheSpookyCat commented 1 year ago

Not as simple as just await'ing it unfortunately :(

TheUntraceable commented 1 year ago

I've taken a look at the issue on my fork, and I found the issue is with on_event being async. If you remove the only await which can be replaced with a asyncio.create_task, it works.

    async def on_event(self, data):
        if self.sock_reader._eof:
            raise PyPresenceException('feed_data after feed_eof')
        if not data:
            return
        self.sock_reader._buffer.extend(data)
        self.sock_reader._wakeup_waiter()
        if (self.sock_reader._transport is not None and
                not self.sock_reader._paused and
                len(self.sock_reader._buffer) > 2 * self.sock_reader._limit):
            try:
                self.sock_reader._transport.pause_reading()
            except NotImplementedError:
                self.sock_reader._transport = None
            else:
                self.sock_reader._paused = True

        payload = json.loads(data[8:].decode('utf-8'))

        if payload["evt"] is not None:
            evt = payload["evt"].lower()
            if evt in self._events:
-                await self._events[evt](payload["data"])
+               asyncio.create_task(self._events[evt](payload["data"]))
            elif evt == 'error':
                raise DiscordError(payload["data"]["code"], payload["data"]["message"])
qwertyquerty commented 1 year ago

Feel free to PR and i'll look into it further