Skip to content

Commit 9cb2cd2

Browse files
committed
refactor(tui): drop dependency windows-curses
1 parent 8d897bb commit 9cb2cd2

File tree

10 files changed

+233
-11
lines changed

10 files changed

+233
-11
lines changed

docs/source/spelling_wordlist.txt

+1
Original file line numberDiff line numberDiff line change
@@ -160,3 +160,4 @@ maxsize
160160
reentrant
161161
env
162162
tty
163+
CPython

nvitop/cli.py

+1-2
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,12 @@
44
"""The interactive NVIDIA-GPU process viewer."""
55

66
import argparse
7-
import curses
87
import os
98
import sys
109
import textwrap
1110

1211
from nvitop.api import HostProcess, libnvml
13-
from nvitop.tui import TUI, USERNAME, Device, colored, libcurses, set_color, setlocale_utf8
12+
from nvitop.tui import TUI, USERNAME, Device, colored, curses, libcurses, set_color, setlocale_utf8
1413
from nvitop.version import __version__
1514

1615

nvitop/tui/__init__.py

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
USERNAME,
99
Device,
1010
colored,
11+
curses,
1112
libcurses,
1213
set_color,
1314
setlocale_utf8,

nvitop/tui/library/curses/__init__.py

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# This file is part of nvitop, the interactive NVIDIA-GPU process viewer.
2+
# License: GNU GPL version 3.
3+
4+
# pylint: disable=missing-module-docstring
5+
6+
from curses import * # noqa: F403 # pylint: disable=redefined-builtin
7+
8+
from nvitop.tui.library.curses import ascii # pylint: disable=redefined-builtin

nvitop/tui/library/curses/ascii.py

+213
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,213 @@
1+
"""Constants and membership tests for ASCII characters"""
2+
3+
# Copied from the CPython repository.
4+
# https://github.com/python/cpython/blob/HEAD/Lib/curses/ascii.py
5+
6+
# pylint: disable=missing-function-docstring
7+
8+
from __future__ import annotations
9+
10+
from typing import overload
11+
12+
13+
NUL = 0x00 # ^@
14+
SOH = 0x01 # ^A
15+
STX = 0x02 # ^B
16+
ETX = 0x03 # ^C
17+
EOT = 0x04 # ^D
18+
ENQ = 0x05 # ^E
19+
ACK = 0x06 # ^F
20+
BEL = 0x07 # ^G
21+
BS = 0x08 # ^H
22+
TAB = 0x09 # ^I
23+
HT = 0x09 # ^I
24+
LF = 0x0A # ^J
25+
NL = 0x0A # ^J
26+
VT = 0x0B # ^K
27+
FF = 0x0C # ^L
28+
CR = 0x0D # ^M
29+
SO = 0x0E # ^N
30+
SI = 0x0F # ^O
31+
DLE = 0x10 # ^P
32+
DC1 = 0x11 # ^Q
33+
DC2 = 0x12 # ^R
34+
DC3 = 0x13 # ^S
35+
DC4 = 0x14 # ^T
36+
NAK = 0x15 # ^U
37+
SYN = 0x16 # ^V
38+
ETB = 0x17 # ^W
39+
CAN = 0x18 # ^X
40+
EM = 0x19 # ^Y
41+
SUB = 0x1A # ^Z
42+
ESC = 0x1B # ^[
43+
FS = 0x1C # ^\
44+
GS = 0x1D # ^]
45+
RS = 0x1E # ^^
46+
US = 0x1F # ^_
47+
SP = 0x20 # space
48+
DEL = 0x7F # delete
49+
50+
controlnames = [
51+
'NUL',
52+
'SOH',
53+
'STX',
54+
'ETX',
55+
'EOT',
56+
'ENQ',
57+
'ACK',
58+
'BEL',
59+
'BS',
60+
'HT',
61+
'LF',
62+
'VT',
63+
'FF',
64+
'CR',
65+
'SO',
66+
'SI',
67+
'DLE',
68+
'DC1',
69+
'DC2',
70+
'DC3',
71+
'DC4',
72+
'NAK',
73+
'SYN',
74+
'ETB',
75+
'CAN',
76+
'EM',
77+
'SUB',
78+
'ESC',
79+
'FS',
80+
'GS',
81+
'RS',
82+
'US',
83+
'SP',
84+
]
85+
86+
87+
def _ctoi(c: int | str) -> int:
88+
if isinstance(c, str):
89+
return ord(c)
90+
return c
91+
92+
93+
def isalnum(c: int | str) -> bool:
94+
return isalpha(c) or isdigit(c)
95+
96+
97+
def isalpha(c: int | str) -> bool:
98+
return isupper(c) or islower(c)
99+
100+
101+
def isascii(c: int | str) -> bool:
102+
return 0 <= _ctoi(c) <= 127
103+
104+
105+
def isblank(c: int | str) -> bool:
106+
return _ctoi(c) in (9, 32)
107+
108+
109+
def iscntrl(c: int | str) -> bool:
110+
return 0 <= _ctoi(c) <= 31 or _ctoi(c) == 127
111+
112+
113+
def isdigit(c: int | str) -> bool:
114+
return 48 <= _ctoi(c) <= 57
115+
116+
117+
def isgraph(c: int | str) -> bool:
118+
return 33 <= _ctoi(c) <= 126
119+
120+
121+
def islower(c: int | str) -> bool:
122+
return 97 <= _ctoi(c) <= 122
123+
124+
125+
def isprint(c: int | str) -> bool:
126+
return 32 <= _ctoi(c) <= 126
127+
128+
129+
def ispunct(c: int | str) -> bool:
130+
return isgraph(c) and not isalnum(c)
131+
132+
133+
def isspace(c: int | str) -> bool:
134+
return _ctoi(c) in (9, 10, 11, 12, 13, 32)
135+
136+
137+
def isupper(c: int | str) -> bool:
138+
return 65 <= _ctoi(c) <= 90
139+
140+
141+
def isxdigit(c: int | str) -> bool:
142+
return isdigit(c) or (65 <= _ctoi(c) <= 70) or (97 <= _ctoi(c) <= 102)
143+
144+
145+
def isctrl(c: int | str) -> bool:
146+
return 0 <= _ctoi(c) < 32
147+
148+
149+
def ismeta(c: int | str) -> bool:
150+
return _ctoi(c) > 127
151+
152+
153+
@overload
154+
def ascii(c: int) -> int: ... # pylint: disable=redefined-builtin
155+
156+
157+
@overload
158+
def ascii(c: str) -> str: ...
159+
160+
161+
def ascii(c: int | str) -> int | str:
162+
if isinstance(c, str):
163+
return chr(_ctoi(c) & 0x7F)
164+
return _ctoi(c) & 0x7F
165+
166+
167+
@overload
168+
def ctrl(c: int) -> int: ...
169+
170+
171+
@overload
172+
def ctrl(c: str) -> str: ...
173+
174+
175+
def ctrl(c: int | str) -> int | str:
176+
if isinstance(c, str):
177+
return chr(_ctoi(c) & 0x1F)
178+
return _ctoi(c) & 0x1F
179+
180+
181+
@overload
182+
def alt(c: int) -> int: ...
183+
184+
185+
@overload
186+
def alt(c: str) -> str: ...
187+
188+
189+
def alt(c: int | str) -> int | str:
190+
if isinstance(c, str):
191+
return chr(_ctoi(c) | 0x80)
192+
return _ctoi(c) | 0x80
193+
194+
195+
@overload
196+
def unctrl(c: int) -> int: ...
197+
198+
199+
@overload
200+
def unctrl(c: str) -> str: ...
201+
202+
203+
def unctrl(c: int | str) -> int | str:
204+
bits = _ctoi(c)
205+
if bits == 0x7F:
206+
rep = '^?'
207+
elif isprint(bits & 0x7F):
208+
rep = chr(bits & 0x7F)
209+
else:
210+
rep = '^' + chr(((bits & 0x7F) | 0x20) + 0x20)
211+
if bits & 0x80:
212+
return '!' + rep
213+
return rep

nvitop/tui/library/keybinding.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,11 @@
55
# pylint: disable=missing-module-docstring,missing-class-docstring,missing-function-docstring
66

77
import copy
8-
import curses
9-
import curses.ascii
108
import string
119
from collections import OrderedDict
1210

11+
from nvitop.tui.library import curses
12+
1313

1414
DIGITS = set(map(ord, string.digits))
1515

nvitop/tui/library/libcurses.py

+4-3
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,11 @@
55

66
import colorsys
77
import contextlib
8-
import curses
98
import locale
109
import os
1110
import signal
1211

12+
from nvitop.tui.library import curses
1313
from nvitop.tui.library.history import GRAPH_SYMBOLS
1414

1515

@@ -161,15 +161,16 @@ def libcurses(colorful=False, light_theme=False):
161161

162162
# Push a Ctrl+C (ascii value 3) to the curses getch stack
163163
def interrupt_handler(signalnum, frame): # pylint: disable=unused-argument
164-
curses.ungetch(3)
164+
curses.ungetch(curses.ascii.ETX)
165165

166166
# Simulate a ^C press in curses when an interrupt is caught
167-
signal.signal(signal.SIGINT, interrupt_handler)
167+
original_interrupt_handler = signal.signal(signal.SIGINT, interrupt_handler)
168168

169169
try:
170170
yield win
171171
finally:
172172
curses.endwin()
173+
signal.signal(signal.SIGINT, original_interrupt_handler)
173174

174175

175176
class CursesShortcuts:

nvitop/tui/library/messagebox.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,12 @@
44

55
# pylint: disable=missing-module-docstring,missing-class-docstring,missing-function-docstring
66

7-
import curses
87
import string
98
import threading
109
import time
1110
from functools import partial
1211

12+
from nvitop.tui.library import curses
1313
from nvitop.tui.library.displayable import Displayable
1414
from nvitop.tui.library.keybinding import normalize_keybinding
1515
from nvitop.tui.library.process import host

nvitop/tui/library/mouse.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
# pylint: disable=missing-module-docstring,missing-class-docstring,missing-function-docstring
66

7-
import curses
7+
from nvitop.tui.library import curses
88

99

1010
class MouseEvent:

nvitop/tui/tui.py

+1-2
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,10 @@
33

44
# pylint: disable=missing-module-docstring,missing-class-docstring,missing-function-docstring
55

6-
import curses
76
import shutil
87
import time
98

10-
from nvitop.tui.library import ALT_KEY, DisplayableContainer, KeyBuffer, KeyMaps, MouseEvent
9+
from nvitop.tui.library import ALT_KEY, DisplayableContainer, KeyBuffer, KeyMaps, MouseEvent, curses
1110
from nvitop.tui.screens import (
1211
BreakLoop,
1312
EnvironScreen,

0 commit comments

Comments
 (0)