Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to await a coroutine in pdb

Tags:

I'm using an async library (asyncpg) and I want to debug some async calls to query the database.

I place a pdb breakpoint and want try out a few queries:

(pdb) await asyncpg.fetch("select * from foo;") *** SyntaxError: 'await' outside function 

It would be great to be able to do this because it would allow me to try out a few SQL queries and see the result, all from the comfort of my debugger.

Is it possible?

like image 614
LondonRob Avatar asked Nov 15 '19 11:11

LondonRob


People also ask

Is await a coroutine?

The async/await pattern is built on two functions: async() to wrap the function call and the resulting value in a coroutine, and await() , which suspends code until the value is ready to be served.

What is Loop Run_in_executor?

run_in_executor is used to manage threads from within an event loop. To this end, it needs to wrap the thread into a Future, which needs to be assigned to an event loop (in one way or another). The reason the method is stored directly in a loop object is probably historical.

Does await always yield?

If its target yield s, await "passes on" the suspension to its own caller. This allows to suspend an entire stack of coroutines that all await each other. If its target returns s, await catches the return value and provides it to its own coroutine.

Is Asyncio thread safe?

Not thread-safe. An asyncio event can be used to notify multiple asyncio tasks that some event has happened.


1 Answers

I had a similar problem debugging the useage of aiofile. I then found a solution using nest_asyncio. For example if one has the following async example script:

import asyncio from aiofile import async_open import nest_asyncio   async def main():     async with async_open("/tmp/hello.txt", 'w+') as afp:         await afp.write("Hello ")         await afp.write("world")         afp.seek(0)         breakpoint()         print(await afp.read())   if __name__=="__main__":     loop = asyncio.get_event_loop()     nest_asyncio.apply(loop)     loop.run_until_complete(main()) 

One can then do:

-> print(await afp.read()) (Pdb) loop = asyncio.get_event_loop() (Pdb) loop.run_until_complete(afp.read()) 'Hello world' (Pdb)  

Admittedly it is a bit more tedious then await asyncpg.fetch("select * from foo;") or await afp.read() but it gets the job done. Hopefully a more elegant solution will come up in the future.

like image 63
M.D. Avatar answered Sep 19 '22 12:09

M.D.