New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Documentation Recommends Broken Pattern #65563
Comments
The documentation recommends replacing sys.stdin with a binary stream currently: https://docs.python.org/3/library/sys.html#sys.stdin This sounds like a bad idea because it will break pretty much everything in Python in the process. As example: >>> import sys
>>> sys.stdin = sys.stdin.detach()
>>> input('Test: ')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: '_io.BufferedReader' object has no attribute 'errors'
>>> sys.stdout = sys.stdout.detach()
>>> print('Hello World!')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'str' does not support the buffer interface |
Initial introduction is 59cb9c074e09. |
That particular revision isn’t sound so bad; I think the next revision, 78fb7f8cd349, which adds the make_streams_binary() function that replaces the variables is a worry though. This is the kind of code I use when I want to write binary data to stdout: output = sys.stdout.detach()
sys.stdout = None # Avoid error message during shutdown, due to output being closed or garbage-collected
output.write(...) This raises two issues:
$ python3 -c 'from sys import stdout; stdout.detach().close()'
Exception ignored in: $ The trailing dollar ($) sign just indicates that there was no newline printed. |
The issue of (mixed) string and binary input/output on the standard streams is still a bit of a work in progress, I think, both documentation wise and code wise. So I'm not sure we know yet what the best practice is to recommend here. I think I agree with Armin, though. I think mentioning reading binary from sys.stdin.buffer is fine, but suggesting replacing the streams is bad. If someone figures that out on their own, it's on their own head, but I don't think we should suggest it. That said, that shutdown error message is probably a bug of one sort or another. |
Sidestepping: The shutdown message is a related issue. TextIOWrapper tends to internally log errors apparently which is super annoying and probably should be fixed. I encountered the same problem with sockets disconnecting wrapped in TextIOWrapper always writing some dummy traceback to stderr which I can't silence. |
New changeset 4621bb82ceec by Antoine Pitrou in branch '3.4': New changeset dbf728f9a2f0 by Antoine Pitrou in branch 'default': |
Thanks for the report, Armin. I've removed that recommendation and changed the surrounding wording to insist that standard streams are always text streams. |
To avoid further problems may I also recommend documenting how exactly people are supposed to wrap sys.stdout and so forth. Clearly putting a StringIO there is insufficient as StringIO does not have a buffer. Something like this maybe? import io
buf = io.BytesIO()
sys.stdout = io.TextIOWrapper(buf,
encoding='utf-8',
errors='strict', # or surrogate-escape as this is the default for stdout now? not sure
line_buffering=True
) |
I would like to know of some situations where you want to write some |
The same situations people wrapped streams before on python 2:
In fact, the reasons people wrap sys.stdout/sys.stderr on 2.x are the same reasons why people would do it on 3.x: they have arbitrary code they did not write and they want to capture what it does. Since you do not know if that is binary or text you need a stream object that behaves the same way as the default one. |
I see, I misunderstood you. You actually want to get back the bytes |
Pretty much, yes. Just that you probably want 'replace' instead. |
Note that in 3.4 we have contextlib.replace_stdout, but it doesn't give any examples of how to construct file-like objects that will work well with it. |
I mean redirect_stdout. |
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
bugs.python.org fields:
The text was updated successfully, but these errors were encountered: