[BUG] live displays and console printing are not thread safe
See original GitHub issueThere seems to be some sort of threading/race issue with the console and the rich handler (or maybe with live dislays in general?) that causes log lines to get lost or misplaced when used with live displays or status displays.
To Reproduce Hereโs a code example that will print out the logs from a queue in a separate thread. Note the log lines arenโt then all expected to be above the status, but I was expecting the status to not interfere with it if itโs thread safe. In particular the status isnโt even getting properly wiped here.
import atexit
import logging
import logging.handlers
import queue
import rich.logging
import rich.console
logger = logging.getLogger(__name__)
console = rich.console.Console()
root_logger = logging.getLogger("")
rhandler = rich.logging.RichHandler(console=console)
que = queue.Queue()
queue_handler = logging.handlers.QueueHandler(que)
listener = logging.handlers.QueueListener(que, rhandler)
root_logger.addHandler(queue_handler)
listener.start()
atexit.register(lambda x: x.stop(), listener)
with console.status("testing"):
for n in range(1000):
logger.error(n)
With this a variety of things can happen, the status can get leftover in a line printed at the same time as a log message or sometimes it can even eat a log message entirely.
Hereโs an example where it ate a line entirely
a lot of the time I get other goofy stuff like this
Platform Gentoo Linux / kitty 0.23.1
Diagnose
pyffstream โฏ python -m rich.diagnose
python -m rich._windows
pip freeze | grep rich
โญโโโโโโโโโโโโโโโโโโโโโโโโโ <class 'rich.console.Console'> โโโโโโโโโโโโโโโโโโโโโโโโโโฎ
โ A high level console interface. โ
โ โ
โ โญโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฎ โ
โ โ <console width=147 ColorSystem.TRUECOLOR> โ โ
โ โฐโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฏ โ
โ โ
โ color_system = 'truecolor' โ
โ encoding = 'utf-8' โ
โ file = <_io.TextIOWrapper name='<stdout>' mode='w' encoding='utf-8'> โ
โ height = 41 โ
โ is_alt_screen = False โ
โ is_dumb_terminal = False โ
โ is_interactive = True โ
โ is_jupyter = False โ
โ is_terminal = True โ
โ legacy_windows = False โ
โ no_color = False โ
โ options = ConsoleOptions( โ
โ size=ConsoleDimensions(width=147, height=41), โ
โ legacy_windows=False, โ
โ min_width=1, โ
โ max_width=147, โ
โ is_terminal=True, โ
โ encoding='utf-8', โ
โ max_height=41, โ
โ justify=None, โ
โ overflow=None, โ
โ no_wrap=False, โ
โ highlight=None, โ
โ markup=None, โ
โ height=None โ
โ ) โ
โ quiet = False โ
โ record = False โ
โ safe_box = True โ
โ size = ConsoleDimensions(width=147, height=41) โ
โ soft_wrap = False โ
โ stderr = False โ
โ style = None โ
โ tab_size = 8 โ
โ width = 147 โ
โฐโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฏ
platform="Linux"
WindowsConsoleFeatures(vt=False, truecolor=False)
rich==10.11.0
Issue Analytics
- State:
- Created 2 years ago
- Comments:10 (7 by maintainers)
Hi, I looked at this problem this weekend and found an ok fix. Basically, the console and the live have two separate locks, and they need to share the same lock to have any chance of dealing with the concurrency. So I made them share that lock and also threw a bunch more code under the locks and now it works. I can make a PR for this as well if the maintainer is ok with it. Not sure how to make a test that proves it fixes anything, though.
https://github.com/willmcgugan/rich/compare/master...Alex7Li:master
@darrenburns @willmcgugan if it is okay I would like to open a new bug to track this so I can get notifications for it
(the bugfix for this was reverted due to problems; this bug is still open)