[Python-Dev] curses: error handling and the lower right margin of the screen (original) (raw)
Aleksejs Popovs aleksejs at mit.edu
Sun Jul 16 22:37:47 EDT 2017
- Previous message (by thread): [Python-Dev] [python-committers] Python 3.3.7 release schedule and end-of-life
- Next message (by thread): [Python-Dev] [RELEASE] Python 3.6.2 is now available
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Hello everyone,
My name is Aleksejs, and this is my first time posting here. I'm working on a Python project (a client for Zephyr, MIT's instant messaging system) that uses curses, and I believe I've found either a bug in the Python curses bindings or a deficiency in their documentation.
The problem has to do with ncurses' cursor advancing behavior. The manpage addch(3x) says:
If the advance is at the right margin: · The cursor automatically wraps to the beginning of the next line. · At the bottom of the current scrolling region, and if scrollok is enabled, the scrolling region is scrolled up one line. · If scrollok is not enabled, writing a character at the lower right margin succeeds. However, an error is returned because it is not possible to wrap to a new line
Python's window.addch(y, x, ch[, attr]) function seems to be internally calling addch or one of the related functions, and so, if scrollok is off and (y, x) is the lower right corner of the screen, addch returns an error, which window.addch then detects and turns into an exception.
I'd like to argue that this is not expected behavior, and does not follow from the documentation. The documentation for window.addch makes no mention of the fact that the cursor is advanced at all, so there's no reason that a user should expect window.addch(height - 1, width - 1, ch) to fail (and the exception raised, "_curses.error: add_wch() returned ERR", is not very helpful in understanding what the deal is). Because the documentation doesn't say anything about the cursor, this is not even an error in any meaningful way, as the character is successfully written to the screen, and wrapping the code in a "try: ... except curses.error: pass" block "fixes" the error.
The same problem affects window.addstr() if the end of the string being painted ends up in the lower right corner.
This behavior is so unintuitive that it is not even accounted for elsewhere in the curses bindings: the implementation of curses.panel.rectangle contains a line [1]
win.addch(lry, lrx, curses.ACSLRCORNER)
which raises an exception when trying to draw a rectangle spanning an entire window (or in fact any rectangle touching the lower right corner). I also wrote a little example script [2] demonstrating the problem.
I believe that this is a problem, but I am not sure how it could be resolved. It seems that there's no way to distinguish this "error" from a legitimate ncurses error. Perhaps the documentation ought to at least mention this behavior, and the implementation of curses.panel.rectangle should check for the case where the rectangle touches the lower right corner and use a try-catch block there.
Best regards, Aleksejs Popovs
[1] https://github.com/python/cpython/blob/3.6/Lib/curses/textpad.py#L16 [2] https://gist.github.com/popoffka/e21299967f5739d18c4fa393fa5cf20b
- Previous message (by thread): [Python-Dev] [python-committers] Python 3.3.7 release schedule and end-of-life
- Next message (by thread): [Python-Dev] [RELEASE] Python 3.6.2 is now available
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]