Skip to content

bpo-42044: Write all bytes to the console in unbuffered mode on Windows #26678

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

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
When the io is flushed in unbuffered mode in Windows, all bytes are now
properly written to the console.
15 changes: 5 additions & 10 deletions Modules/_io/winconsoleio.c
Original file line number Diff line number Diff line change
Expand Up @@ -978,16 +978,6 @@ _io__WindowsConsoleIO_write_impl(winconsoleio *self, Py_buffer *b)

Py_BEGIN_ALLOW_THREADS
wlen = MultiByteToWideChar(CP_UTF8, 0, b->buf, len, NULL, 0);

/* issue11395 there is an unspecified upper bound on how many bytes
can be written at once. We cap at 32k - the caller will have to
handle partial writes.
Since we don't know how many input bytes are being ignored, we
have to reduce and recalculate. */
while (wlen > 32766 / sizeof(wchar_t)) {
len /= 2;
wlen = MultiByteToWideChar(CP_UTF8, 0, b->buf, len, NULL, 0);
}
Py_END_ALLOW_THREADS

if (!wlen)
Expand All @@ -998,6 +988,11 @@ _io__WindowsConsoleIO_write_impl(winconsoleio *self, Py_buffer *b)
Py_BEGIN_ALLOW_THREADS
wlen = MultiByteToWideChar(CP_UTF8, 0, b->buf, len, wbuf, wlen);
if (wlen) {
/* Note that it's possible that this would fail to print big strings
* on Windows 7 (before Windows 8 LPC-based pseudo-files were used
* for I/O and would be limited to a 64 KiB heap).
* As Windows 7 is currently unsupported, that's Ok.
*/
res = WriteConsoleW(handle, wbuf, wlen, &n, NULL);
if (res && n < wlen) {
/* Wrote fewer characters than expected, which means our
Expand Down