Using pdb to make an async call act synchronous call

2,239 views
Skip to first unread message

Al Johri

unread,
Dec 8, 2015, 1:45:57 AM12/8/15
to python-tulip
Hi,

Similar to how Tornado has a IOLoop.current().run_sync method, is there anyway that while I'm in pdb I can schedule a coroutine or future, have it execute immediately, and block until it finishes?

For example, if I'm writing to a database and I need to test something, I'd like to be able to type within pdb "await db.insert(mydocument)" for testing purposes and have it execute immediately.

Just curious if this is even within the realm of possibility; I'm rather new to asyncio so I apologize if this has been discussed before or is completely preposterous.

I've tried to do things like, write a coroutine called "debug" such as:

async def debug():
    await db
.insert(mydocument)

and then within pdb do something along the lines of

loop.run_until_complete(debug())

but obviously this can't be done as the loop is already running.

Would love any insight on how to achieve this. Thanks!

Al

Ben Darnell

unread,
Dec 8, 2015, 10:06:50 AM12/8/15
to Al Johri, python-tulip
If the event loop is already running, then Tornado's IOLoop.run_sync() won't work either (it may appear to work because we don't do enough checking for improper combinations of run_sync() and start(), but it's not safe).

Instead, you should do something like `debug().add_done_callback(lambda f: pdb.set_trace())` and then `continue` (I'm not a pdb user so I'm not sure of the exact commands), so pdb will let the outer event loop run and then break back in once the given coroutine is finished.

-Ben

Al Johri

unread,
Dec 8, 2015, 10:45:03 AM12/8/15
to python-tulip, al.j...@gmail.com, b...@bendarnell.com
Hi Ben,
  1. It's my understanding that debug in of itself is a "coroutine function" and running debug() returns a "coroutine object" that can be scheduled within the even loop by creating a task or using ensure_future. Are you saying that I should do

    asyncio.ensure_future(debug().add_done_callback(lambda f: pdb.set_trace()))

    Sorry if that was supposed to be obvious.

  2. And if I do this, will I be able to use "up" within pdb to access the local frame of debug? I'd like to see the result of my test code.
Thanks for the help!

Ben Darnell

unread,
Dec 8, 2015, 10:49:36 AM12/8/15
to Al Johri, python-tulip
On Tue, Dec 8, 2015 at 10:45 AM, Al Johri <al.j...@gmail.com> wrote:
Hi Ben,
  1. It's my understanding that debug in of itself is a "coroutine function" and running debug() returns a "coroutine object" that can be scheduled within the even loop by creating a task or using ensure_future. Are you saying that I should do

    asyncio.ensure_future(debug().add_done_callback(lambda f: pdb.set_trace()))

    Sorry if that was supposed to be obvious.

Ah, right. No, it's not obvious; I was thinking of Tornado's @gen.coroutine. It's a little more complicated for native coroutines and asyncio. I'm not sure if there's a better way for this than ensure_future.
 

  1. And if I do this, will I be able to use "up" within pdb to access the local frame of debug? I'd like to see the result of my test code.
You can see the return value of debug() in f.result(). But `debug()` is `down`, not `up` relative to the breakpoint, and you can't look into it because it has already returned. To see its locals you'll have to set a breakpoint inside debug() itself.
Reply all
Reply to author
Forward
0 new messages