minrk / wurlitzer

Capture C-level stdout/stderr in Python
MIT License
194 stars 24 forks source link

`sys_pipes()` hangs on mac os #84

Closed JakeSummers closed 7 months ago

JakeSummers commented 7 months ago

Running the following code causes sys_pipes() to hang on mac os.

__init__.py file:

from wurlitzer import sys_pipes

print("Before")
with sys_pipes():
    print("After sys pipes")
print("Done")

Output is:

image

Computer info:

image

Version info:

$ poetry show wurlitzer
 name         : wurlitzer
 version      : 3.0.3
 description  : Capture C-level output in context managers

$ python --version
Python 3.10.12

I cannot reproduce when running in docker.

JakeSummers commented 7 months ago

Maybe I am mis-using this tooling:

https://github.com/minrk/wurlitzer/blob/d7f3ed1f11994a3d8309821cbf3ef4757831470d/wurlitzer.py#L537

minrk commented 7 months ago

You're right - sys_pipes is for forwarding things to sys.stdout, when sys.stdout has already been replaced with something (e.g. in a Jupyter notebook).

I think perhaps what you want is wurlitzer.pipes().

minrk commented 6 months ago

Hopefully #85 will give you a more meaningful error message that should point you in the right direction, rather than hanging uninformatively.

JakeSummers commented 6 months ago

Thanks for the reply @minrk .

What I am trying to do is map stderr to stdout.

When tensorflow starts up it writes to stderr. This shows up in my logging environment as an error. What i would like to do is redirect stderr to stdout so that these messages show up as info instead.

EDIT - Logged a separate issue to discuss this issue in: https://github.com/minrk/wurlitzer/issues/87

JakeSummers commented 6 months ago

Strangely, it looks like updating from 3.0.3 to 3.1.0 has resolved this issue.

This code now works:

import sys
from contextlib import redirect_stderr

from wurlitzer import sys_pipes

# Tensorflow prints messages to stderr when it is imported.  These show up in
# GCP logging as errors.  To avoid this we are redirecting stderr to stdout.
#   See: https://github.com/tensorflow/tensorflow/issues/62770
#   And: https://stackoverflow.com/questions/77796003/how-to-redirect-tensorflow-import-errors-from-stderr-to-stdout

with redirect_stderr(sys.stdout):
    with sys_pipes():
        import tensorflow  # noqa: W0611
minrk commented 6 months ago

Yes, 3.1 optimizes forwarding to a file with a fileno() method in a way that shouldn't block. But that code ought to work, since it's doing this:

# redirect_stderr:
sys.stderr = sys.stdout
# sys_pipes:
forward sys.__stdout__ to sys.stdout # this hung in 3.0, not in 3.1; this is why I have `stdout=None` in my example, to skip this step
forward sys.__stderr__ to sys.stderr # which is actually sys.stdout thanks to redirect_stderr