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

patch_stdout sometimes throws exception?

Open
#731 5 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

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

Description

Sometimes I get this exception when I enter input.

Traceback (most recent call last):
  File "/opt/homebrew/Cellar/python/3.7.0/Frameworks/Python.framework/Versions/3.7/lib/python3.7/asyncio/events.py", line 88, in _run
    self._context.run(self._callback, *self._args)
  File "prompt_toolkit/eventloop/context.py", line 115, in new_func
    return func(*a, **kw)
  File "prompt_toolkit/patch_stdout.py", line 97, in write_and_flush_in_loop
    run_in_terminal(write_and_flush, in_executor=False)
  File "prompt_toolkit/application/run_in_terminal.py", line 41, in run_in_terminal
    return run_coroutine_in_terminal(async_func, render_cli_done=render_cli_done)
  File "prompt_toolkit/application/run_in_terminal.py", line 62, in run_coroutine_in_terminal
    assert app._is_running
AssertionError

My input processing loop looks like this:

    parser = user_input_parser()
    validator = Validator.from_callable(
      lambda _: PROMPT_STATE.enabled, error_message="Terminal not available")
    while True:
      try:
        with patch_stdout(raw=True):
          user_input = await session.prompt(
            lambda: "> " if PROMPT_STATE.enabled else "", async_=True,
            rprompt=lambda: PROMPT_STATE.status, validator=validator,
            validate_while_typing=True)

        if not PROMPT_STATE.enabled:
          continue
      except KeyboardInterrupt:
        return

      parse_input(user_input.strip())

I'm dumping things to the screen via python logging module but AFAIK I don't have any threads going on. Maybe there's a bug where prompt toolkit is launching threads unnecessarily? It seems like there's a few threads doing sleeps in key_processor which seems weird (wouldn't there only be 1?) but not sure if related or expected behaviour. Is it possible I'm doing something very wrong?

MainThread <_MainThread(MainThread, started 140735655584640)>
  File "shell.py", line 1404, in <module>
    sys.exit(main(sys.argv[1:]) or 0)
  File "shell.py", line 1398, in main
    loop.run_until_complete(prompt_task)
  File "/opt/homebrew/Cellar/python/3.7.0/Frameworks/Python.framework/Versions/3.7/lib/python3.7/asyncio/base_events.py", line 555, in run_until_complete
    self.run_forever()
  File "/opt/homebrew/Cellar/python/3.7.0/Frameworks/Python.framework/Versions/3.7/lib/python3.7/asyncio/base_events.py", line 523, in run_forever
    self._run_once()
  File "/opt/homebrew/Cellar/python/3.7.0/Frameworks/Python.framework/Versions/3.7/lib/python3.7/asyncio/base_events.py", line 1758, in _run_once
    handle._run()
  File "/opt/homebrew/Cellar/python/3.7.0/Frameworks/Python.framework/Versions/3.7/lib/python3.7/asyncio/events.py", line 100, in _run
    self._loop.call_exception_handler(context)
  File "/opt/homebrew/Cellar/python/3.7.0/Frameworks/Python.framework/Versions/3.7/lib/python3.7/asyncio/base_events.py", line 1626, in call_exception_handler
    self._exception_handler(self, context)
  File "shell.py", line 1272, in exception_handler
    file=exception_stderr)

Thread-1 <Thread(Thread-1, started daemon 123145533894656)>
  File "/opt/homebrew/Cellar/python/3.7.0/Frameworks/Python.framework/Versions/3.7/lib/python3.7/threading.py", line 885, in _bootstrap
    self._bootstrap_inner()
  File "/opt/homebrew/Cellar/python/3.7.0/Frameworks/Python.framework/Versions/3.7/lib/python3.7/threading.py", line 917, in _bootstrap_inner
    self.run()
  File "/opt/homebrew/Cellar/python/3.7.0/Frameworks/Python.framework/Versions/3.7/lib/python3.7/threading.py", line 865, in run
    self._target(*self._args, **self._kwargs)
  File "prompt_toolkit/eventloop/utils.py", line 33, in run
    result = self.target()
  File "prompt_toolkit/key_binding/key_processor.py", line 378, in wait
    time.sleep(timeout)

Thread-2 <Thread(Thread-2, started daemon 123145539149824)>
  File "/opt/homebrew/Cellar/python/3.7.0/Frameworks/Python.framework/Versions/3.7/lib/python3.7/threading.py", line 885, in _bootstrap
    self._bootstrap_inner()
  File "/opt/homebrew/Cellar/python/3.7.0/Frameworks/Python.framework/Versions/3.7/lib/python3.7/threading.py", line 917, in _bootstrap_inner
    self.run()
  File "/opt/homebrew/Cellar/python/3.7.0/Frameworks/Python.framework/Versions/3.7/lib/python3.7/threading.py", line 865, in run
    self._target(*self._args, **self._kwargs)
  File "prompt_toolkit/eventloop/utils.py", line 33, in run
    result = self.target()
  File "prompt_toolkit/key_binding/key_processor.py", line 378, in wait
    time.sleep(timeout)

Thread-3 <Thread(Thread-3, started daemon 123145544404992)>
  File "/opt/homebrew/Cellar/python/3.7.0/Frameworks/Python.framework/Versions/3.7/lib/python3.7/threading.py", line 885, in _bootstrap
    self._bootstrap_inner()
  File "/opt/homebrew/Cellar/python/3.7.0/Frameworks/Python.framework/Versions/3.7/lib/python3.7/threading.py", line 917, in _bootstrap_inner
    self.run()
  File "/opt/homebrew/Cellar/python/3.7.0/Frameworks/Python.framework/Versions/3.7/lib/python3.7/threading.py", line 865, in run
    self._target(*self._args, **self._kwargs)
  File "prompt_toolkit/eventloop/utils.py", line 33, in run
    result = self.target()
  File "prompt_toolkit/application/application.py", line 562, in <lambda>
    lambda: auto_flush_input(counter), _daemon=True)
  File "prompt_toolkit/application/application.py", line 567, in auto_flush_input
    time.sleep(self.ttimeoutlen)

Thread-4 <Thread(Thread-4, started daemon 123145549660160)>
  File "/opt/homebrew/Cellar/python/3.7.0/Frameworks/Python.framework/Versions/3.7/lib/python3.7/threading.py", line 885, in _bootstrap
    self._bootstrap_inner()
  File "/opt/homebrew/Cellar/python/3.7.0/Frameworks/Python.framework/Versions/3.7/lib/python3.7/threading.py", line 917, in _bootstrap_inner
    self.run()
  File "/opt/homebrew/Cellar/python/3.7.0/Frameworks/Python.framework/Versions/3.7/lib/python3.7/threading.py", line 865, in run
    self._target(*self._args, **self._kwargs)
  File "prompt_toolkit/eventloop/utils.py", line 33, in run
    result = self.target()
  File "prompt_toolkit/key_binding/key_processor.py", line 378, in wait
    time.sleep(timeout)

Thread-5 <Thread(Thread-5, started daemon 123145554915328)>
  File "/opt/homebrew/Cellar/python/3.7.0/Frameworks/Python.framework/Versions/3.7/lib/python3.7/threading.py", line 885, in _bootstrap
    self._bootstrap_inner()
  File "/opt/homebrew/Cellar/python/3.7.0/Frameworks/Python.framework/Versions/3.7/lib/python3.7/threading.py", line 917, in _bootstrap_inner
    self.run()
  File "/opt/homebrew/Cellar/python/3.7.0/Frameworks/Python.framework/Versions/3.7/lib/python3.7/threading.py", line 865, in run
    self._target(*self._args, **self._kwargs)
  File "prompt_toolkit/eventloop/utils.py", line 33, in run
    result = self.target()
  File "prompt_toolkit/application/application.py", line 562, in <lambda>
    lambda: auto_flush_input(counter), _daemon=True)
  File "prompt_toolkit/application/application.py", line 567, in auto_flush_input
    time.sleep(self.ttimeoutlen)

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 reproducing the traceback with patch_stdout and an async session.prompt call. Trace the interaction between prompt_toolkit/patch_stdout.py, application/run_in_terminal.py, application/application.py, and key_binding/key_processor.py, especially the _is_running assertion. Done means the reported input or logging scenario no longer raises AssertionError.

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.