From d84f0f90efd1560e5bd6904932babaac80d3af3b Mon Sep 17 00:00:00 2001 From: Anai-Guo Date: Sun, 12 Apr 2026 22:54:55 -0700 Subject: [PATCH] fix suppress_stdout_stderr not working in Jupyter notebooks ipykernel replaces sys.stdout/stderr with OutStream objects that store their own copy of the original file descriptor in _original_stdstream_copy. This bypasses the dup2 redirect used by suppress_stdout_stderr, so output still appears even with verbose=False. Fix by temporarily pointing _original_stdstream_copy at the real fd before redirecting, and restoring it on exit. Fixes #872 --- llama_cpp/_utils.py | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/llama_cpp/_utils.py b/llama_cpp/_utils.py index 29628193bb..7c2741d4fd 100644 --- a/llama_cpp/_utils.py +++ b/llama_cpp/_utils.py @@ -34,6 +34,21 @@ def __enter__(self): self.old_stdout = self.sys.stdout self.old_stderr = self.sys.stderr + # In Jupyter notebooks, ipykernel replaces sys.stdout/stderr with + # OutStream objects that hold their own copy of the original fd in + # _original_stdstream_copy. This bypasses our dup2 redirect, so we + # need to point that copy at the real fd temporarily. + self._saved_stdout_copy = getattr( + self.sys.stdout, "_original_stdstream_copy", None + ) + self._saved_stderr_copy = getattr( + self.sys.stderr, "_original_stdstream_copy", None + ) + if self._saved_stdout_copy is not None: + self.sys.stdout._original_stdstream_copy = self.old_stdout_fileno_undup + if self._saved_stderr_copy is not None: + self.sys.stderr._original_stdstream_copy = self.old_stderr_fileno_undup + self.os.dup2(outnull_file.fileno(), self.old_stdout_fileno_undup) self.os.dup2(errnull_file.fileno(), self.old_stderr_fileno_undup) @@ -45,7 +60,6 @@ def __exit__(self, *_): if self.disable: return - # Check if sys.stdout and sys.stderr have fileno method self.sys.stdout = self.old_stdout self.sys.stderr = self.old_stderr @@ -55,6 +69,12 @@ def __exit__(self, *_): self.os.close(self.old_stdout_fileno) self.os.close(self.old_stderr_fileno) + # Restore ipykernel's OutStream fd copies + if self._saved_stdout_copy is not None: + self.sys.stdout._original_stdstream_copy = self._saved_stdout_copy + if self._saved_stderr_copy is not None: + self.sys.stderr._original_stdstream_copy = self._saved_stderr_copy + class MetaSingleton(type): """