Upgrading to prompt_toolkit 3.0 — prompt_toolkit 3.0.50 documentation (original) (raw)
There are two major changes in 3.0 to be aware of:
- First, prompt_toolkit uses the asyncio event loop natively, rather then using its own implementations of event loops. This means that all coroutines are now asyncio coroutines, and all Futures are asyncio futures. Asynchronous generators became real asynchronous generators as well.
- Prompt_toolkit uses type annotations (almost) everywhere. This should not break any code, but its very helpful in many ways.
There are some minor breaking changes:
- The dialogs API had to change (see below).
Detecting the prompt_toolkit version¶
Detecting whether version 3 is being used can be done as follows:
from prompt_toolkit import version as ptk_version
PTK3 = ptk_version.startswith('3.')
Fixing calls to get_event_loop¶
Every usage of get_event_loop
has to be fixed. An easy way to do this is by changing the imports like this:
if PTK3: from asyncio import get_event_loop else: from prompt_toolkit.eventloop import get_event_loop
Notice that for prompt_toolkit 2.0, get_event_loop
returns a prompt_toolkitEventLoop
object. This is not an asyncio eventloop, but the API is similar.
There are some changes to the eventloop API:
version 2.0 | version 3.0 (asyncio) |
---|---|
loop.run_in_executor(callback) | loop.run_in_executor(None, callback) |
loop.call_from_executor(callback) | loop.call_soon_threadsafe(callback) |
Running on top of asyncio¶
For 2.0, you had tell prompt_toolkit to run on top of the asyncio event loop. Now it’s the default. So, you can simply remove the following two lines:
from prompt_toolkit.eventloop.defaults import use_asyncio_event_loop use_asyncio_event_loop()
There is a few little breaking changes though. The following:
For 2.0
result = await PromptSession().prompt('Say something: ', async_=True)
has to be changed into:
For 3.0
result = await PromptSession().prompt_async('Say something: ')
Further, it’s impossible to call the prompt() function within an asyncio application (within a coroutine), because it will try to run the event loop again. In that case, always use prompt_async().
Changes to the dialog functions¶
The original way of using dialog boxes looked like this:
from prompt_toolkit.shortcuts import input_dialog
result = input_dialog(title='...', text='...')
Now, the dialog functions return a prompt_toolkit Application object. You have to call either its run
or run_async
method to display the dialog. Theasync_
parameter has been removed everywhere.
if PTK3: result = input_dialog(title='...', text='...').run() else: result = input_dialog(title='...', text='...')
Or
if PTK3: result = await input_dialog(title='...', text='...').run_async() else: result = await input_dialog(title='...', text='...', async_=True)