Skip to content

fix(logging): avoid race condition in live logging with background threads#14564

Open
goingforstudying-ctrl wants to merge 3 commits into
pytest-dev:mainfrom
goingforstudying-ctrl:fix/live-logging-race-condition
Open

fix(logging): avoid race condition in live logging with background threads#14564
goingforstudying-ctrl wants to merge 3 commits into
pytest-dev:mainfrom
goingforstudying-ctrl:fix/live-logging-race-condition

Conversation

@goingforstudying-ctrl
Copy link
Copy Markdown

Fixes #13693

Replace capture suspension in _LiveLoggingStreamHandler.emit() with direct writes to the original stdout stream. This prevents race conditions where background threads write to stdout/stderr while capture is suspended, causing lost output in capfd/capsys fixtures.

The previous implementation used capture_manager.global_and_fixture_disabled() which temporarily restored sys.stdout/stderr to their original values. When background threads logged during this window, their writes bypassed capture. The fix creates a temporary TerminalWriter pointing to the original stdout, allowing log messages to appear on the terminal while keeping capture active for all threads.

@goingforstudying-ctrl goingforstudying-ctrl force-pushed the fix/live-logging-race-condition branch from fb477cc to 1106249 Compare June 6, 2026 14:33
@goingforstudying-ctrl
Copy link
Copy Markdown
Author

Pushed a fix for the test_live_logging_suspends_capture failure. The MockCaptureManager mock in the test needed a get_original_stdout() method to match the new API used by _LiveLoggingStreamHandler.emit(). Also removed the now-obsolete assertions on global_and_fixture_disabled call tracking since the handler no longer suspends capture.

Let me know if anything else needs adjustment.

@goingforstudying-ctrl goingforstudying-ctrl force-pushed the fix/live-logging-race-condition branch 2 times, most recently from bf4262a to cdbf7c5 Compare June 6, 2026 15:26
@psf-chronographer psf-chronographer Bot added the bot:chronographer:provided (automation) changelog entry is part of PR label Jun 6, 2026
@goingforstudying-ctrl goingforstudying-ctrl force-pushed the fix/live-logging-race-condition branch from 8db3f47 to 4a676c6 Compare June 6, 2026 16:33
@goingforstudying-ctrl
Copy link
Copy Markdown
Author

Fixed the mypy error in get_original_stdout().

  • Changed return type to TextIO | None since sys.__stdout__ can be None
  • Added a None guard in _LiveLoggingStreamHandler.emit() before writing to the stream

Should be green now.

@goingforstudying-ctrl goingforstudying-ctrl force-pushed the fix/live-logging-race-condition branch 6 times, most recently from 8b703ef to 07df891 Compare June 6, 2026 18:54
…reads

Replace global capture suspension in _LiveLoggingStreamHandler.emit()
with a temporary redirect of the TerminalWriter's output file to the
original stdout. This prevents race conditions where background threads
write to stdout/stderr while capture is suspended, causing lost output
in capfd/capsys fixtures.

Fixes pytest-dev#13693
@goingforstudying-ctrl goingforstudying-ctrl force-pushed the fix/live-logging-race-condition branch from f60be95 to df5d575 Compare June 6, 2026 19:15
@goingforstudying-ctrl goingforstudying-ctrl force-pushed the fix/live-logging-race-condition branch from 464b0f8 to fd26370 Compare June 6, 2026 20:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bot:chronographer:provided (automation) changelog entry is part of PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Live logging from background threads is racy and can make capfd/capsys lose messages

1 participant