prompt-toolkit / ptpython

A better Python REPL
BSD 3-Clause "New" or "Revised" License
5.23k stars 281 forks source link

async / loop is already running #555

Closed redhog closed 1 year ago

redhog commented 1 year ago

I'm developing https://github.com/redhog/pieshell , a python based shell language. As an option, I support PTPython for nicer editing. I have recently converted Pieshell to use asyncio.

To provide e.g. tab completion in PTPython, I need to implement the __dir__ method. However, that one would need to call async code in pieshell. Doing that using asyncio.get_event_loop().run_until_complete() fails with a message about the main loop already running.

Is there a way around this (e.g. an async version of __dir__)?

jonathanslenders commented 1 year ago

Hi @redhog,

__dir__ can't be async. It could spawn an event loop (in theory), but it can't wait for tasks in an already running event loop. To me, it does not make sense to start async code from within __dir__, because that would imply that listing the attributes of an object requires potentially doing I/O, which is weird. I don't think there's a good workaround, even doing blocking I/O in __dir__ is not a good idea, because if it is called in an event loop, that would freeze the loop. Ptpython uses the Jedi library for code completion, so there's not much we can do here anyway.

redhog commented 1 year ago

My workaround was to figure out how to make ptpython use a separate main loop from my own code. I actually do io in dir: Specifically, I list directory contents and call load shell command completions from bash.