pythonpython-3.xubuntu-18.04gnome-terminalpython-curses

Use utf-8 character for curses border


I can't use character for curses border with.

Code example:

import curses

stdscr = curses.initscr()
c = '█'
stdscr.border(c, c, c, c, c, c, c, c)
stdscr.getch()

I obtain this error:

OverflowError: byte doesn't fit in chtype

I can however use addstr for write some utf-8 character like this:

stdscr.addstr(0, 0, "█")

Thanks for your help.


Solution

  • The problem is that the Python curses package is just a wrapper over the ncurses C library. And in ncurses (https://linux.die.net/man/3/ncurses), a character is represented as a chtype, (character and attribute data) where the character is a C char type which is just a byte on common systems.

    The underlying border function expects each character of the border to be a single byte, while the 'FULL BLOCK' that you are trying to use is the unicode character U+2588 or the UTF-8 byte string b'\xe2\x96\x88'. That is the reason for the error message: you try to store a 3 bytes sequence into a single byte variable.

    It works fine for addstr because that function expects a string and accepts the 3 bytes sequence. But it would break with addch which expect a single string.

    Said differently, the curses module will not accept multibyte UTF-8 sequences except where it expects strings.

    Possible workarounds: