On 2021-01-17, Grant Edwards <grant.b.edwa...@gmail.com> wrote: > On 2021-01-17, Greg Ewing <greg.ew...@canterbury.ac.nz> wrote: >> On 17/01/21 12:40 pm, Chris Angelico wrote: >>> This is true. However, at some point, the boundary is crossed from >>> Python into the C library. Something, at that point, knows. It's very >>> common to have a flush option available, so it should be used. >> >> I'm wondering whether the problem in this particular case stems >> from trying to use parts of curses without initialising it >> properly. > > No. > >> I expect that initialising curses would put stdout into some kind of >> unbuffered mode, and the rest of it assumes that this has been done. > > No.
I should clarify. The case in question isn't using curses. It's only using the terminfo calls, and the terminfo stuff is being properly initialized. As I previously explained, the problem with the OP's code is that ncurses.putp() is writing to libc's FILE *stdout (which does buffering). Python's stdout/stderr objects do not use FILE *stdout/*stderr, but instead do their own buffering before writing to the file descriptors. There are three ways to do what the OP is trying to do: 1. Use ctypes to call fflush(stdout) before doing a print() or sys.stdout.write(), and call sys.stdout.flush() before calling curses.putp(). 2. Don't use putp(). Use the terminfo calls to construct the escape sequences and then write them with print() or sys.stdout.write(). 3. Replace sys.stdout.buffer and sys.stderr.buffer with a custom objects that uses ctypes to call fwrite() instead of writing directly to the file descriptor. I've posted examples of #1 and #2, I'll try #3 when I have more spare time. I thought it might be possible to use curses.tputs() with a callback that writes to sys.stdout, but the curses module doesn't provide tput, it only provides putp (which is far less flexible). -- Grant -- https://mail.python.org/mailman/listinfo/python-list