Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

curses and SIGWINCH do not work properly with Hy. #1921

Closed
atisharma opened this issue Nov 19, 2020 · 5 comments · Fixed by #2214
Closed

curses and SIGWINCH do not work properly with Hy. #1921

atisharma opened this issue Nov 19, 2020 · 5 comments · Fixed by #2214
Labels

Comments

@atisharma
Copy link

After importing curses under hy, curses is unable to detect the size of the terminal as it is resized.
This manifests as curses.LINES and curses.COLS not being updated, stdscr.getmaxyx not working and so on.

However, the workaround of launching the hy program from python with:

import hy
import curses
from main import main_event_loop

if __name__ == "__main__":
    curses.wrapper(main_event_loop, ...)

allows curses to dynamically detect the size of the terminal.

I conclude therefore the problem is with the hy binary. My (limited) understanding acquired during tracking down the source of this problem is that curses uses the SIGWINCH signal, so perhaps that is a place to look.

Void linux x86 64bit, python 3.9.0
Freebsd 12.2, python 3.8.6
hy 0.19.0 (reported by pip) installed from git master branch via pip

@Kodiologist
Copy link
Member

Can you provide a reproducible example? I can't try that program without main.

@atisharma
Copy link
Author

Sorry, here are the two files required for a minimal example.

main.py:

import hy
import curses
from main import main

if __name__ == "__main__":
    curses.wrapper(main)

main.hy:

(import curses)
(import [time [sleep]])

(defn main [stdscr]
 (setv window (.newwin curses curses.LINES curses.COLS))
 (.clear stdscr)
 (while True
  (.update_lines_cols curses)
  (.resize window curses.LINES curses.COLS)
  (.addnstr window 1 1 f"{curses.LINES} {curses.COLS}" 30)
  (.addnstr window 2 1 f"{(.getmaxyx stdscr)}" 30)
  (.refresh window)
  (sleep 0.1)))
   
(if (= __name__ "__main__")
 (.wrapper curses main))

@Kodiologist
Copy link
Member

Thanks, I can confirm this.

While unrelated to this bug, I should warn you against making one file named main.py and another named main.hy in the same directory: there's no guarantee that import main will get the one you're thinking of.

@atisharma
Copy link
Author

Thank you. Yes, I wouldn't normally have such a name collision, it was just quickly knocked up for the purposes of the example.

@Kodiologist
Copy link
Member

Hilariously, this turns out to be a bug that's been in CPython for 13 years. Hy triggers it with import readline in hy.completer, which in turn is imported by hy.cmdline. Let's see if I can work around this for the typical case by just delaying the import of Readline until it's really necessary.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants