-
-
Notifications
You must be signed in to change notification settings - Fork 32k
ValueError: can't have unbuffered text I/O for io.open(1, 'wt', 0) #61606
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
Comments
The io library rejects unbuffered text I/O, but this is not documented - and in fact can be manually worked around: Note that writing to a pipe doesn't really need to care about buffering anyway, if the user writes 300 characters, the codec will output a single block and the IO made will be one write: This test script: When run under strace -c does exactly 10 writes: so the performance is predictable. IMO it doesn't make sense to prohibit unbuffered text write I/O. readers may be another matter, but that doesn't suffer the same latency issues. |
The proposed workaround seems to work ("wb" instead of "wt"!), with the following restrictions:
IMO this explains why it's not a supported combination in io.open(). |
Huh, I didn't realise idna would retain data! But that will still be within the TextIOWrapper itself, right? And a stream opened 'wt' cannot be read from anyway, so the read1 limitation is irrelevant. |
Yes. And I just noticed that the _io module (the C version) will also buffer encoded bytes, up to f._CHUNK_SIZE. On the other hand, TextIOWrapper is broken for buffering codecs, encode() is never called with final=True >>> import io
>>> buffer = io.BytesIO() # <-- not really buffered, right?
>>> output = io.TextIOWrapper(buffer, encoding='idna')
>>> output.write("www.somesite.com")
16
>>> print(buffer.getvalue())
b'' # <-- ok, _CHUNK_SIZE buffering
>>> output.flush()
>>> print(buffer.getvalue())
b'www.somesite.' # <-- the last word is missing!
>>> output.close()
>>> print(buffer.getvalue())
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: I/O operation on closed file. And it's even worse with python 2.7:: >>> import io as io
>>> buffer = io.BytesIO()
>>> output = io.TextIOWrapper(buffer, encoding='idna')
>>> output.write("www.somesite.com")
Traceback (most recent call last):
File "<stdin>", line 3, in <module>
TypeError: must be unicode, not str |
Since 3.3 TextIOWrapper works with raw IO objects (bpo-12591).
Use write_through=True to disable this. |
It won't be technically unbuffered, though. |
It is documented that buffering=0 is not supported in text mode. Look a handful of paragraphs down from <https://docs.python.org/release/3.7.2/library/functions.html#open\>: “Pass 0 to switch buffering off (only allowed in binary mode)” Amaury’s problem with the IDNA buffering encoder has now been reported separately in bpo-35611. |
Also improves non-blocking support (pythongh-57531) and unbuffered support (pythongh-61606)
Also improves non-blocking support (pythongh-57531) and unbuffered support (pythongh-61606)
Also improves non-blocking support (pythongh-57531) and unbuffered support (pythongh-61606)
Also improves non-blocking support (pythongh-57531) and unbuffered support (pythongh-61606)
Also improves non-blocking support (pythongh-57531) and unbuffered support (pythongh-61606)
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: