diff --git a/Lib/test/test_subprocess.py b/Lib/test/test_subprocess.py old mode 100644 new mode 100755 --- a/Lib/test/test_subprocess.py +++ b/Lib/test/test_subprocess.py @@ -1217,13 +1217,26 @@ subprocess.call([sys.executable, "-c", "import sys; sys.exit(0)"], startupinfo=startupinfo) + def _with_new_console(self, command): + # start a subprocess with CREATE_NEW_CONSOLE and the given command + CREATE_NEW_CONSOLE = 16 + sys.stderr.write(" a DOS box should flash briefly ...\n") + subprocess.check_call(command, creationflags=CREATE_NEW_CONSOLE) + def test_creationflags(self): # creationflags argument - CREATE_NEW_CONSOLE = 16 - sys.stderr.write(" a DOS box should flash briefly ...\n") - subprocess.call(sys.executable + - ' -c "import time; time.sleep(0.25)"', - creationflags=CREATE_NEW_CONSOLE) + self._with_new_console(sys.executable + + ' -c "import time; time.sleep(0.25)"') + + def test_stdout_large(self): + # see: issue #11395 + self._with_new_console([sys.executable, "-c", + "print(b'a' * 66000)"]) + + def test_stdout_binlarge(self): + # see: issue #11395 + self._with_new_console([sys.executable, "-u", "-c", + "print(b'a' * 66000)"]) def test_invalid_args(self): # invalid arguments should raise ValueError diff --git a/Modules/_io/fileio.c b/Modules/_io/fileio.c --- a/Modules/_io/fileio.c +++ b/Modules/_io/fileio.c @@ -57,6 +57,9 @@ signed int seekable : 2; /* -1 means unknown */ unsigned int closefd : 1; unsigned int deallocating: 1; +#if defined(MS_WIN64) || defined(MS_WINDOWS) + unsigned int isatty : 1; +#endif PyObject *weakreflist; PyObject *dict; } fileio; @@ -161,6 +164,9 @@ self->writable = 0; self->seekable = -1; self->closefd = 1; +#if defined(MS_WIN64) || defined(MS_WINDOWS) + self->isatty = 0; +#endif self->weakreflist = NULL; } @@ -357,6 +363,11 @@ goto error; self->fd = fd; self->closefd = closefd; +#if defined(MS_WIN64) || defined(MS_WINDOWS) + /* Check if the fd represents a console output (it should already been opened), + to work around WriteConsole limitations when we write to it later. */ + self->isatty = isatty(self->fd) ? 1 : 0; +#endif } else { self->closefd = 1; @@ -712,6 +723,12 @@ errno = 0; len = pbuf.len; #if defined(MS_WIN64) || defined(MS_WINDOWS) +#define WIN_CONSOLE_BUFSIZ 32767 + /* Issue #11395: Resolve "IOError: [Errno 12] Not enough space" + when writing into std* in Windows console if the written + length is large enough. */ + if (self->isatty && len > WIN_CONSOLE_BUFSIZ) + len = WIN_CONSOLE_BUFSIZ; if (len > INT_MAX) len = INT_MAX; n = write(self->fd, pbuf.buf, (int)len);