Mickey Perlstein
Mickey Perlstein

Reputation: 4124

Debugging an async program in the pycharm debugger

My request is to get debugging data from the debugger and pycharm prompt:

Lets say I have an-old-style python synchronous program with a bug:

   def listdir(self, remote_path):
         with ssh.connect(self.connection_settings['host'], username=self.connection_settings['username'],
                                    password=self.connection_settings['password']) as conn:
            with conn.start_sftp_client() as sftp:
                sftp.chdir(remote_path) # breakpoint here

                files = sftp.readdir()
                files_name = [file.filename for file in files]

                return files_name

I would stop it, go to the debugger, click on debugger console->show python prompt and then debug my issues in runtime:

> sftp.getcwd()
bad_user_location
> sftp.chdir(good_base_location)
> sftp.readdir()

Just rewriting the code on the fly and testing state and runtime. (This has allways been how I debug, using the immediate window in Microsoft langauges development, and REPL in python and other script languages.

Now I have an async program:

  async def listdir(self, remote_path):
        async with asyncssh.connect(self.connection_settings['host'], username=self.connection_settings['username'],
                                    password=self.connection_settings['password']) as conn:
            async with conn.start_sftp_client() as sftp:
                await sftp.chdir(remote_path)  # breakpoint here


                files = await sftp.readdir()
                files_name = [file.filename for file in files]

                return files_name

I stop it, go to the debugger, click on debugger console->show python prompt and then debug my issues in runtime:

> sftp.getcwd()
<CoroWrapper SFTPClient.getcwd() running at....truncated info
  1. I try getting the event loop and running on it, but i cannot await without a function.
  2. I installed IPython 7 that allows event_loop, but it wont run the task, just add to the event loop, as its built for jupyter and not this usecase
  3. I tried creating a new event loop but there can be only one in a thread.
  4. I tried using nest_asyncio and apply, but >nest_asyncio.events.new_event_loop().create_task(sftp.getcwd()) but it just adds it to the loop, it doesnt run it. <Task pending coro=<SFTPClient.getcwd() running at...
  5. I think my best bet is to create a second thread, create a new loop there, and await tasks from that loop. something like question about 2 loops but I am having difficulties with this. something like:
   >d.run_sync(sftp.getcwd())
   directory_name
   >d.run_sync(sft.chdir(somewhere_else))
   0 # exit code

I found in channels v2.0 something like this under Andrew Gadwins great article

   >asgiref.sync.async_to_sync(sftp.getcwd())
   ><asgiref.sync.AsyncToSync object at 0x7ff94c7b37e0> ... created at <input>:1> was never yielded from
   >ERROR:asyncio:<CoroWrapper SFTPClient.getcwd()
  1. Maybe I could attach jupyternotebook to my running debugger, but this would be my last resort as it's not really a good maintainable solution

I think its vital to be able to debug coroutines at runtime so i value your solutions greatly.

Thanks

Upvotes: 9

Views: 4538

Answers (2)

Andrii Liekariev
Andrii Liekariev

Reputation: 1

If you need to call await during debugging in PyCharm, there is Evaluate Async Code plugin for that. A screenshot from the plugin page: awaiting a coro during debug

Upvotes: 0

Raydel Miranda
Raydel Miranda

Reputation: 14360

Asyncio support for the debugger [EXPERIMENTAL FEATURE]

Debug Console allows you to enter async calls and use await keyword outside the functions to check your asynchronous code while debugging.

enter image description here

Upvotes: 3

Related Questions