Skip to content

Commit

Permalink
feat: use workaround to fix python3.12 compatibility error
Browse files Browse the repository at this point in the history
  • Loading branch information
mecaneer23 committed Feb 22, 2024
1 parent 2b67b1f commit 66ed3bd
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 5 deletions.
6 changes: 4 additions & 2 deletions src/get_args.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,14 @@
from typing import Any

try:
from curses import wrapper # pyright: ignore
# from curses import wrapper # pyright: ignore
from src.working_initscr import wrapper # pyright: ignore

_DEFAULT_TKINTER_GUI = False
except ImportError:

def wrapper(_: Any) -> str: # pylint: disable=missing-function-docstring
def wrapper(_: Any, *args: Any, **kwargs: Any) -> Any: # pylint: disable=missing-function-docstring
_ = (args, kwargs)
return _CHECKBOX_OPTIONS[1]

_DEFAULT_TKINTER_GUI = True # pyright: ignore[reportConstantRedefinition]
Expand Down
54 changes: 54 additions & 0 deletions src/working_initscr.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
"""
For some reason curses initscr doesn't work on python3.12,
presumably due to a compilation bug or something. This
module provides a functional workaround.
Thanks to https://github.com/zephyrproject-rtos/windows-curses/issues/50
for the inspiration.
"""

import curses
from typing import Any, Callable

import _curses


def initscr() -> Any:
"""Return a stdscr that should be properly initialized"""
stdscr = _curses.initscr() # pyright: ignore
for key, value in _curses.__dict__.items():
if key[0:4] == "ACS_" or key in ("LINES", "COLS"):
setattr(curses, key, value)
return stdscr # pyright: ignore


def wrapper(func: Callable[..., Any], /, *args: Any, **kwds: Any) -> Any:
"""
Wrapper function that initializes curses and calls another function,
restoring normal keyboard/screen behavior on error.
The callable object 'func' is then passed the main window 'stdscr'
as its first argument, followed by any other arguments passed to
wrapper().
"""

try:
stdscr = initscr()

curses.noecho()
curses.cbreak()

stdscr.keypad(1)

_curses.start_color() # pyright: ignore
if hasattr(_curses, 'COLORS'):
curses.COLORS = _curses.COLORS # pyright: ignore
if hasattr(_curses, 'COLOR_PAIRS'):
curses.COLOR_PAIRS = _curses.COLOR_PAIRS # pyright: ignore

return func(stdscr, *args, **kwds)
finally:
if 'stdscr' in locals():
stdscr.keypad(0) # pyright: ignore
curses.echo()
curses.nocbreak()
curses.endwin()
4 changes: 3 additions & 1 deletion todo.py
Original file line number Diff line number Diff line change
Expand Up @@ -632,4 +632,6 @@ def main(stdscr: Any) -> int:
print(f"{HEADER}:")
print_todos(None, file_string_to_todos(read_file(FILENAME)), Cursor(0))
sys_exit()
curses.wrapper(main)

from src.working_initscr import wrapper # pylint: disable=ungrouped-imports
wrapper(main)
2 changes: 0 additions & 2 deletions todo.txt
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
-1 fix strikethrough
-1 fix long lines (longer than width // 2 - 1)
-1 fix moving down onto a toggled line
-3 make it work on windows
-3 appears to be a compatibility problem with python3.12
-4 implement multiline todos
-4 allow multiline paste
-4 allow multiline print
Expand Down

0 comments on commit 66ed3bd

Please sign in to comment.