This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author andriusl
Recipients andriusl
Date 2019-03-05.11:17:19
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1551784639.74.0.156563550591.issue36193@roundup.psfhosted.org>
In-reply-to
Content
It looks like logging library uses always first assigned stderr object and won't change it even if it was reset.

capture_output function redirects stdout and stderr to io.StringIO object, saves what was captured in string and returns it. And then context manager resets back stdout and stderr where it should be originally. Though it seems logging library ignores that.

Here is the code I encountered issue with:

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 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

Here is what I get running this code:

dummy test
WARNING:root:dummy test

dummy test
--- 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
Call stack:
  File "tt.py", line 43, in <module>
    capture_output(dummy)  # won't work anymore.
  File "tt.py", line 28, in capture_output
    target(*args, **kwargs)
  File "tt.py", line 36, in dummy
    logging.warning('dummy test')
Message: 'dummy test'
Arguments: ()

dummy2 test

dummy2 test


P.S. here is original question I asked on stack overflow: https://stackoverflow.com/questions/54999650/python3-redirected-stderr-not-reset-properly. I got suggestion to report it as a bug.
History
Date User Action Args
2019-03-05 11:17:19andriuslsetrecipients: + andriusl
2019-03-05 11:17:19andriuslsetmessageid: <1551784639.74.0.156563550591.issue36193@roundup.psfhosted.org>
2019-03-05 11:17:19andriusllinkissue36193 messages
2019-03-05 11:17:19andriuslcreate