[issue11633] regression: print buffers output when end=''

STINNER Victor report at bugs.python.org
Wed Mar 23 10:25:11 CET 2011


STINNER Victor <victor.stinner at haypocalc.com> added the comment:

amaury> When python is run from a console, sys.stdout is line buffered.
amaury> sys.stdout.write() flushes if there is a carriage return.
amaury> No need to change anything here.

Anatoly would like a flush after all calls to print().

> print() could call file.flush() if file.isatty(), *after* the multiple
> calls to file.write().

I vote +0 to change print(), call sys.stdout.flush(), if:

 - file option is not used (and so, sys.stdout is used)
 - sys.stdout is a TTY
 - end option is used (fast heuristic to check if print will write a newline or not, a better one whould be to check if end contains a newline character or not, but we had to check for \n and/or \r, for a little gain)

But I don't want to change print() for print(text, file=file), because it would make Python slower and print(... file=file) is not used to an interactive prompt or to display informations to the user.

> Behavior is same when pasting into interactive interpreter ...
> I presume interpreter flushes before or after printing next prompt.

Did you wrote all commands on the same line? Python does change stdout buffer in interactive mode:
------------
    if (Py_UnbufferedStdioFlag) {
#ifdef HAVE_SETVBUF
        setvbuf(stdin,  (char *)NULL, _IONBF, BUFSIZ);
        setvbuf(stdout, (char *)NULL, _IONBF, BUFSIZ);
        setvbuf(stderr, (char *)NULL, _IONBF, BUFSIZ);
#else /* !HAVE_SETVBUF */
        setbuf(stdin,  (char *)NULL);
        setbuf(stdout, (char *)NULL);
        setbuf(stderr, (char *)NULL);
#endif /* !HAVE_SETVBUF */
    }
    else if (Py_InteractiveFlag) {
#ifdef MS_WINDOWS
        /* Doesn't have to have line-buffered -- use unbuffered */
        /* Any set[v]buf(stdin, ...) screws up Tkinter :-( */
        setvbuf(stdout, (char *)NULL, _IONBF, BUFSIZ);
#else /* !MS_WINDOWS */
#ifdef HAVE_SETVBUF
        setvbuf(stdin,  (char *)NULL, _IOLBF, BUFSIZ);
        setvbuf(stdout, (char *)NULL, _IOLBF, BUFSIZ);
#endif /* HAVE_SETVBUF */
#endif /* !MS_WINDOWS */
        /* Leave stderr alone - it should be unbuffered anyway. */
    }
#ifdef __VMS
    else {
        setvbuf (stdout, (char *)NULL, _IOLBF, BUFSIZ);
    }
#endif /* __VMS */
------------
(it doesn't check if stdout is a TTY or not, but I don't think that it is very useful to use the interactive mode outside a TTY)

> I have always experienced and expected Python's print to screen
> to be immediately visible. I thought that was pretty standard
> in other languages with a print-to-screen separate from
> general file-write.

Did you try Perl, Ruby, bash and other languages? I know that at least the C language requires an explicit call to fflush(stdout). I always used that.

> Terry, IDLE is completely different, its sys.stdout completely
> bypasses the new io stack, and there is no buffering...

As I wrote: "unbuffered mode" is not implemented for TextIOWrapper. So even with python3 -u, sys.stdout.write("abc") doesn't flush immediatly into the underlying FileIO.

----------

_______________________________________
Python tracker <report at bugs.python.org>
<http://bugs.python.org/issue11633>
_______________________________________


More information about the Python-bugs-list mailing list