Install & Compatibility
Where this runs
tested against v3.1.1 · pip install
no network on importno background threads
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
muslpy 3.10–3.95 runs
installs and imports cleanly · install 0.0s · import 0.038s · 17.8MB
glibcpy 3.10–3.95 runs
installs and imports cleanly · install 1.5s · import 0.046s · 18MB
16MB installed
● package 16MB
Code
Verified usage
Verified import paths — ran on the pinned version, not inferred.
pipes
✓ from wurlitzer import pipes
sys_pipes
✓ from wurlitzer import sys_pipes
Wurlitzer
✓ from wurlitzer import Wurlitzer
Class-based context manager, less commonly used directly than `pipes` or `sys_pipes`.
STDOUT
✓ from wurlitzer import STDOUT
Used with `pipes` to redirect stderr to stdout.
PIPE
✓ from wurlitzer import PIPE
Placeholder for pipe output in `pipes`.
This quickstart demonstrates how to use `wurlitzer.pipes` to capture C-level `stdout` and `stderr` into Python `StringIO` objects, and `wurlitzer.sys_pipes` to forward C-level output directly to Python's `sys.stdout` and `sys.stderr` streams. It uses `ctypes` to simulate C functions printing to the console.
import ctypes
import io
from wurlitzer import pipes, STDOUT
# Simulate a C function that prints to stdout/stderr
libc = ctypes.CDLL(None) # Load standard C library
def c_printf(msg):
libc.printf(b'%s\n', msg.encode('utf8'))
def c_fprintf_stderr(msg):
# Find stderr pointer, differs slightly by OS
try:
c_stderr_p = ctypes.c_void_p.in_dll(libc, 'stderr')
except ValueError:
c_stderr_p = ctypes.c_void_p.in_dll(libc, '__stderrp')
libc.fprintf(c_stderr_p, b'%s\n', msg.encode('utf8'))
# Example 1: Capture stdout and stderr separately
out_buf = io.StringIO()
err_buf = io.StringIO()
with pipes(stdout=out_buf, stderr=err_buf):
c_printf('Hello from C stdout!')
c_fprintf_stderr('Hello from C stderr!')
print(f"Captured STDOUT: '{out_buf.getvalue().strip()}'")
print(f"Captured STDERR: '{err_buf.getvalue().strip()}'")
# Example 2: Forward C-level stdout/stderr to Python's sys.stdout/stderr
# which might already be redirected (e.g., in a Jupyter notebook)
from wurlitzer import sys_pipes
print("\n--- Using sys_pipes (output below is from Python's streams) ---")
with sys_pipes():
c_printf('C stdout via sys_pipes!')
c_fprintf_stderr('C stderr via sys_pipes!')
print("--- End sys_pipes example ---")
Debug
Known issues
gotchaWhen using `sys_pipes` in complex environments (e.g., deeply nested context managers or with prior redirections of `sys.stdout`/`sys.stderr`), older versions of `wurlitzer` (prior to 3.1.0) on macOS could sometimes hang. This was due to specific interactions with file descriptor handling.fixUpgrade to `wurlitzer` version 3.1.0 or newer. If upgrading is not possible, ensure `sys.stdout` and `sys.stderr` are not redirected to each other before entering the `sys_pipes` context, or use `pipes(stdout=None, stderr=sys.stdout)` for specific redirection needs.
affects: <3.1.0
gotcha`wurlitzer` operates by redirecting C-level file descriptors. While it uses a background thread to forward output, long-running C code that extensively holds the Python GIL (Global Interpreter Lock) might still cause perceived blocking or delays in output processing, especially if not configured to write to a file-backed pipe.fixFor C code that might hold the GIL for extended periods, consider using `pipes` with a file-like object that has a `fileno()` method (e.g., `open('log.txt', 'ab')`) as the `stdout` or `stderr` target, as `wurlitzer` version 3.1 and newer optimizes this for GIL-less capture. This allows the C code to write directly to the file without needing Python's I/O, minimizing GIL contention. affects: All versions
deprecatedWhile `wurlitzer` 3.1.1 officially supports Python >=3.5, there has been a GitHub Pull Request to drop support for Python versions older than 3.8. Future major or minor releases may officially drop support for Python 3.5, 3.6, and 3.7.fixIt is recommended to use `wurlitzer` with Python 3.8 or newer to ensure compatibility with future releases and benefit from ongoing maintenance.
affects: Future versions (post 3.1.1)
Upgrade
Version history
3.1.1latest on PyPI · released Jun 12, 2024
Audit
Dependencies
pythonrequiredRuntime environment