Search code examples
pythonncursespython-curses

_curses.error: addwstr() returned ERR on changing nlines to 1 on newwin method


The code is:

from curses import *
from curses.panel import *

def main(stdscr):
    start_color()
    curs_set(0)
    init_pair(1, COLOR_BLACK, COLOR_CYAN)

    posy = posx = 0
    window = newwin(1, 1, posy, posx)
    panel = new_panel(window)
    window.addstr('*', color_pair(1))
    update_panels()
    doupdate()

    while True:
        key = stdscr.getch()

        if key == ord('j'):
            posy+=1
        elif key == ord('k'):
            posy-=1
        elif key == ord('h'):
            posx-=1
        elif key == ord('l'):
            posx+=1
        elif key == ord('q'):
            endwin()
            break
        panel.move(posy,posx)
        update_panels()
        doupdate()
if __name__ == '__main__':
    wrapper(main)

I am getting this error:

Traceback (most recent call last):
  File "test_1_height_error.py", line 34, in <module>
    wrapper(main)
  File "/usr/lib/python3.7/curses/__init__.py", line 94, in wrapper
    return func(stdscr, *args, **kwds)
  File "test_1_height_error.py", line 12, in main
    window.addstr('*', color_pair(1))
_curses.error: addwstr() returned ERR

However if I change line 10 from window = newwin(1, 1, posy, posx) to window = newwin(2, 1, posy, posx) i.e change the nlines args to greater than 1 then it works fine.

I really don't understand why I am getting this issue.


Solution

  • addch and anything built from it (such as addstr) prints the text and advances the cursor past what was printed.

    A 1x1 window isn't big enough to write one character and wrap to the next line (since you filled the line). When the window was 2x1, it could do that.

    ncurses (any X/Open Curses) has other functions (such as addchstr) that don't advance the cursor, but I don't see those mentioned in the python curses reference.

    Since ncurses will print the character that you want, and it's an isolated case, the workaround is to wrap the addstr in a try-statement, e.g.,

    try:
        window.addstr('*', color_pair(1))
    except curses.error:
        pass