Я написал функцию, которая могла бы захватывать stdout
и stderr
в строку при выполнении какой-либо другой функции.Сначала он работал, но есть проблема с неправильным сбросом stderr.
Он захватывает stderr первый раз, но во второй раз пытается использовать закрытый строковый буфер, когда я ожидаю, что он будет использовать newбуфер.
Вот мой код:
import io
import sys
import contextlib
from typing import Optional
import logging
def capture_output(
target: object,
args: Optional[tuple] = None,
kwargs: Optional[dict] = None) -> str:
"""Redirect stdout and stderr into string buffer and capture it.
target object is executed with optional args, kwargs and all stdout/
stderr that is captured, returned in string form.
Args:
target: object to execute, usually a function.
args: target positional arguments (default: {None})
kwargs: target keyword arguments (default: {None})
"""
if not args:
args = ()
if not kwargs:
kwargs = {}
# with _setup_capture_output() as sio:
with io.StringIO() as sio:
with contextlib.redirect_stdout(sio), contextlib.redirect_stderr(sio):
target(*args, **kwargs)
output = sio.getvalue()
print(output)
def dummy():
print('dummy test')
logging.warning('dummy test')
def dummy2():
print('dummy2 test')
capture_output(dummy) # works
capture_output(dummy) # won't work anymore.
capture_output(dummy2) # works
capture_output(dummy2) # works
Запуск capture_output
во второй раз (если необходимо захватить stderr, как в случае logging.warning
), он выдает ошибку:
--- Logging error ---
Traceback (most recent call last):
File "/usr/lib/python3.5/logging/__init__.py", line 982, in emit
stream.write(msg)
ValueError: I/O operation on closed file
PS Если я попытаюсь поймать только стандартный вывод (печать), то он не взорвется при любом количестве вызовов capture_output
.