Skip to content

contextlib.redirect_stdout/stderr does not work with pytest-run-parallel #130148

Closed as not planned
@15r10nk

Description

@15r10nk

Bug report

Bug description:

redirect_stdout/stderr does not work if freethreading is enabled.

The following example shows the problem:

# /// script
# dependencies = [
#   "pytest",
#   "pytest-run-parallel"
# ]
# ///


from contextlib import redirect_stdout
from io import StringIO
import time


def test_redirect():
    text=StringIO()
    with redirect_stdout(text):
        print("hello")
        time.sleep(1)
        print("hello")

    assert text.getvalue()=="hello\nhello\n"


if __name__ == "__main__":
    import pytest
    pytest.main(["--parallel-threads=5",__file__])

output:

❯ uv run -p 3.13t bug.py
================================== test session starts ==================================
platform linux -- Python 3.13.1, pytest-8.3.4, pluggy-1.5.0
rootdir: /home/frank/projects/bugs/pytest_redirect
plugins: run-parallel-0.3.1
collected 1 item                                                                        

bug.py F                                                                          [100%]

======================================= FAILURES ========================================
_____________________________________ test_redirect _____________________________________

    def test_redirect():
        text=StringIO()
        with redirect_stdout(text):
            print("hello")
            time.sleep(1)
            print("hello")
    
>       assert text.getvalue()=="hello\nhello\n"
E       AssertionError: assert 'hello\n' == 'hello\nhello\n'
E         
E           hello
E         - hello

bug.py:22: AssertionError
================================ short test summary info ================================
FAILED bug.py::test_redirect - AssertionError: assert 'hello\n' == 'hello\nhello\n'
=================================== 1 failed in 1.04s ===================================

The underlying problem is probably the global sys.stdout/stderr state which is shared between threads.
Is it possible to make these thread local?

CPython versions tested on:

3.13

Operating systems tested on:

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions