Exploring terminfo

Grant Edwards grant.b.edwards at gmail.com
Sun Jan 17 16:56:45 EST 2021


On 2021-01-17, Grant Edwards <grant.b.edwards at gmail.com> wrote:
> On 2021-01-17, Greg Ewing <greg.ewing at 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

 




More information about the Python-list mailing list