prompt-toolkit / prompt-toolkit/python-prompt-toolkit

Why does my prompt-toolkit Dialog flicker on terminal output with asyncio and patch_stout?

Open
#1,698 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Python
Stars
10.6k
Forks
815
PR merge metrics
No merged PRs in 30d

Description

When running a prompt-toolkit Dialog it will flicker if there is terminal output from a different asyncio task.

I am using the context with patch_stdout() within a task as mentioned in the doc, at least as far as I understand it. I read somewhere that starting with prompt-toolkit 3.0 it uses the default asyncio event loop and does not create one itself.

And since asyncio.run always creates a new event loop and closes it at the end and the context manager is within that, I have no clue what could be the reason for the flickering. What am I missing?

(Python 3.9, prompt-toolkit 3.0.36)

This is a MCVE:

import asyncio
from prompt_toolkit.patch_stdout import patch_stdout
from prompt_toolkit.shortcuts.dialogs import _create_app, _return_none
from prompt_toolkit.widgets import Button, Dialog, Label

dialog_align = Dialog(
    title='Please align',
    body=Label(text="init", dont_extend_height=True),
    buttons=[Button(text='Start measurement', width=21, handler=_return_none)],
    with_background=True,
)

async def prompt_align():

    return await _create_app(dialog_align, style=None).run_async()


async def main_datasource():

    while True:
        await asyncio.sleep(0.5)
        print("test")


async def main():

    with patch_stdout():

        task1 = asyncio.create_task(prompt_align())
        task2 = asyncio.create_task(main_datasource())

        await asyncio.gather(task1, task2)


if __name__ == "__main__":

    try:
        from asyncio import run
    except ImportError:
        asyncio.run_until_complete(main())
    else:
        
        asyncio.run(main())

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by running the provided MCVE with Python 3.9 and prompt-toolkit 3.0.36. Trace patch_stdout(), _create_app(...).run_async(), and the concurrent print task to identify the flicker; done means the cause and a verified resolution or limitation are documented.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
cli
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
30/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.