Skip to content

Commit 382c31d

Browse files
committed
Use a stub rather than TYPE_CHECKING
1 parent 871ca4d commit 382c31d

27 files changed

+267
-326
lines changed

kittens/ask/main.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,13 @@
99
from kitty.cli import parse_args
1010
from kitty.cli_stub import AskCLIOptions
1111
from kitty.constants import cache_dir
12+
from kitty.typing import BossType
1213

1314
from ..tui.handler import result_handler
1415
from ..tui.operations import alternate_screen, styled
1516

1617
if TYPE_CHECKING:
1718
import readline
18-
import kitty
1919
else:
2020
readline = None
2121

@@ -127,7 +127,7 @@ def main(args: List[str]) -> Response:
127127

128128

129129
@result_handler()
130-
def handle_result(args: List[str], data: Response, target_window_id: int, boss: 'kitty.boss.Boss') -> None:
130+
def handle_result(args: List[str], data: Response, target_window_id: int, boss: BossType) -> None:
131131
if data['response'] is not None:
132132
func, *args = data['items']
133133
getattr(boss, func)(data['response'], *args)

kittens/hints/main.py

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@
1010
from gettext import gettext as _
1111
from itertools import repeat
1212
from typing import (
13-
TYPE_CHECKING, Any, Callable, Dict, Generator, Iterable, List, Optional,
14-
Pattern, Sequence, Set, Tuple, Type, cast
13+
Any, Callable, Dict, Generator, Iterable, List, Optional, Pattern,
14+
Sequence, Set, Tuple, Type, cast
1515
)
1616

1717
from kitty.cli import parse_args
@@ -20,30 +20,26 @@
2020
from kitty.key_encoding import (
2121
KeyEvent, backspace_key, enter_key, key_defs as K
2222
)
23+
from kitty.typing import BossType, KittyCommonOpts
2324
from kitty.utils import ScreenSize, screen_size_function
2425

2526
from ..tui.handler import Handler, result_handler
2627
from ..tui.loop import Loop
2728
from ..tui.operations import faint, styled
2829

29-
if TYPE_CHECKING:
30-
from kitty.config import KittyCommonOpts
31-
from kitty.boss import Boss
32-
3330

3431
@lru_cache()
35-
def kitty_common_opts() -> 'KittyCommonOpts':
32+
def kitty_common_opts() -> KittyCommonOpts:
3633
import json
3734
v = os.environ.get('KITTY_COMMON_OPTS')
3835
if v:
39-
return cast('KittyCommonOpts', json.loads(v))
36+
return cast(KittyCommonOpts, json.loads(v))
4037
from kitty.config import common_opts_as_dict
4138
return common_opts_as_dict()
4239

4340

4441
DEFAULT_HINT_ALPHABET = string.digits + string.ascii_lowercase
4542
DEFAULT_REGEX = r'(?m)^\s*(.+)\s*$'
46-
screen_size = screen_size_function()
4743
ESCAPE = K['ESCAPE']
4844

4945

@@ -346,7 +342,7 @@ def parse_input(text: str) -> str:
346342
try:
347343
cols = int(os.environ['OVERLAID_WINDOW_COLS'])
348344
except KeyError:
349-
cols = screen_size().cols
345+
cols = screen_size_function()().cols
350346
return convert_text(text, cols)
351347

352348

@@ -560,7 +556,7 @@ def main(args: List[str]) -> Optional[Dict[str, Any]]:
560556
return run(opts, text, items)
561557

562558

563-
def linenum_handle_result(args: List[str], data: Dict[str, Any], target_window_id: int, boss: 'Boss', extra_cli_args: Sequence[str], *a: Any) -> None:
559+
def linenum_handle_result(args: List[str], data: Dict[str, Any], target_window_id: int, boss: BossType, extra_cli_args: Sequence[str], *a: Any) -> None:
564560
for m, g in zip(data['match'], data['groupdicts']):
565561
if m:
566562
path, line = g['path'], g['line']
@@ -589,7 +585,7 @@ def linenum_handle_result(args: List[str], data: Dict[str, Any], target_window_i
589585

590586

591587
@result_handler(type_of_input='screen')
592-
def handle_result(args: List[str], data: Dict[str, Any], target_window_id: int, boss: 'Boss') -> None:
588+
def handle_result(args: List[str], data: Dict[str, Any], target_window_id: int, boss: BossType) -> None:
593589
if data['customize_processing']:
594590
m = load_custom_processor(data['customize_processing'])
595591
if 'handle_result' in m:

kittens/icat/main.py

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,13 @@
1313
from math import ceil
1414
from tempfile import NamedTemporaryFile
1515
from typing import (
16-
TYPE_CHECKING, Dict, Generator, List, NamedTuple, Optional, Pattern, Tuple,
17-
Union
16+
Dict, Generator, List, NamedTuple, Optional, Pattern, Tuple, Union
1817
)
1918

2019
from kitty.cli import parse_args
2120
from kitty.cli_stub import IcatCLIOptions
2221
from kitty.constants import appname
22+
from kitty.typing import GRT_f, GRT_t
2323
from kitty.utils import (
2424
TTYIO, ScreenSize, ScreenSizeGetter, fit_image, screen_size_function
2525
)
@@ -30,9 +30,6 @@
3030
)
3131
from ..tui.operations import clear_images_on_screen
3232

33-
if TYPE_CHECKING:
34-
from ..tui.images import GRT_f, GRT_t # noqa
35-
3633
OPTIONS = '''\
3734
--align
3835
type=choices

kittens/tui/handler.py

Lines changed: 21 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -3,35 +3,29 @@
33
# License: GPL v3 Copyright: 2018, Kovid Goyal <kovid at kovidgoyal.net>
44

55

6+
from types import TracebackType
67
from typing import (
7-
TYPE_CHECKING, Any, Callable, ContextManager, Dict, Optional, Sequence, Type,
8-
Union
8+
Any, Callable, ContextManager, Dict, Optional, Sequence, Type, Union
99
)
1010

11-
if TYPE_CHECKING:
12-
from kitty.utils import ScreenSize
13-
from .loop import TermManager, Loop, Debug, MouseEvent
14-
from .images import ImageManager
15-
from kitty.conf.utils import KittensKeyAction
16-
from kitty.boss import Boss
17-
from kitty.key_encoding import KeyEvent
18-
from types import TracebackType
19-
ScreenSize, TermManager, Loop, Debug, KeyEvent, MouseEvent, TracebackType, Boss, ImageManager
20-
import asyncio
11+
from kitty.typing import (
12+
AbstractEventLoop, BossType, Debug, ImageManagerType, KeyEventType,
13+
KittensKeyActionType, LoopType, MouseEvent, ScreenSize, TermManagerType
14+
)
2115

2216

2317
class Handler:
2418

25-
image_manager_class: Optional[Type['ImageManager']] = None
19+
image_manager_class: Optional[Type[ImageManagerType]] = None
2620

2721
def _initialize(
2822
self,
29-
screen_size: 'ScreenSize',
30-
term_manager: 'TermManager',
23+
screen_size: ScreenSize,
24+
term_manager: TermManagerType,
3125
schedule_write: Callable[[bytes], None],
32-
tui_loop: 'Loop',
33-
debug: 'Debug',
34-
image_manager: Optional['ImageManager'] = None
26+
tui_loop: LoopType,
27+
debug: Debug,
28+
image_manager: Optional[ImageManagerType] = None
3529
) -> None:
3630
from .operations import commander
3731
self.screen_size = screen_size
@@ -43,23 +37,23 @@ def _initialize(
4337
self._image_manager = image_manager
4438

4539
@property
46-
def image_manager(self) -> 'ImageManager':
40+
def image_manager(self) -> ImageManagerType:
4741
assert self._image_manager is not None
4842
return self._image_manager
4943

5044
@property
51-
def asyncio_loop(self) -> 'asyncio.AbstractEventLoop':
45+
def asyncio_loop(self) -> AbstractEventLoop:
5246
return self._tui_loop.asycio_loop
5347

54-
def add_shortcut(self, action: 'KittensKeyAction', key: str, mods: Optional[int] = None, is_text: Optional[bool] = False) -> None:
48+
def add_shortcut(self, action: KittensKeyActionType, key: str, mods: Optional[int] = None, is_text: Optional[bool] = False) -> None:
5549
if not hasattr(self, '_text_shortcuts'):
5650
self._text_shortcuts, self._key_shortcuts = {}, {}
5751
if is_text:
5852
self._text_shortcuts[key] = action
5953
else:
6054
self._key_shortcuts[(key, mods or 0)] = action
6155

62-
def shortcut_action(self, key_event_or_text: Union[str, 'KeyEvent']) -> Optional['KittensKeyAction']:
56+
def shortcut_action(self, key_event_or_text: Union[str, KeyEventType]) -> Optional[KittensKeyActionType]:
6357
if isinstance(key_event_or_text, str):
6458
return self._text_shortcuts.get(key_event_or_text)
6559
return self._key_shortcuts.get((key_event_or_text.key, key_event_or_text.mods))
@@ -70,7 +64,7 @@ def __enter__(self) -> None:
7064
self.debug.fobj = self
7165
self.initialize()
7266

73-
def __exit__(self, etype: type, value: Exception, tb: 'TracebackType') -> None:
67+
def __exit__(self, etype: type, value: Exception, tb: TracebackType) -> None:
7468
del self.debug.fobj
7569
self.finalize()
7670
if self._image_manager is not None:
@@ -82,7 +76,7 @@ def initialize(self) -> None:
8276
def finalize(self) -> None:
8377
pass
8478

85-
def on_resize(self, screen_size: 'ScreenSize') -> None:
79+
def on_resize(self, screen_size: ScreenSize) -> None:
8680
self.screen_size = screen_size
8781

8882
def quit_loop(self, return_code: Optional[int] = None) -> None:
@@ -94,7 +88,7 @@ def on_term(self) -> None:
9488
def on_text(self, text: str, in_bracketed_paste: bool = False) -> None:
9589
pass
9690

97-
def on_key(self, key_event: 'KeyEvent') -> None:
91+
def on_key(self, key_event: KeyEventType) -> None:
9892
pass
9993

10094
def on_mouse(self, mouse_event: 'MouseEvent') -> None:
@@ -127,7 +121,7 @@ def print(self, *args: object, sep: str = ' ', end: str = '\r\n') -> None:
127121
data = sep.join(map(str, args)) + end
128122
self.write(data)
129123

130-
def suspend(self) -> ContextManager['TermManager']:
124+
def suspend(self) -> ContextManager[TermManagerType]:
131125
return self._term_manager.suspend()
132126

133127

@@ -141,7 +135,7 @@ def __init__(self, impl: Callable, type_of_input: Optional[str], no_ui: bool):
141135
self.no_ui = no_ui
142136
self.type_of_input = type_of_input
143137

144-
def __call__(self, args: Sequence[str], data: Any, target_window_id: int, boss: 'Boss') -> Any:
138+
def __call__(self, args: Sequence[str], data: Any, target_window_id: int, boss: BossType) -> Any:
145139
return self.impl(args, data, target_window_id, boss)
146140

147141

kittens/tui/images.py

Lines changed: 14 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,13 @@
1010
from contextlib import suppress
1111
from itertools import count
1212
from typing import (
13-
TYPE_CHECKING, Any, DefaultDict, Deque, Dict, List, Optional, Sequence,
14-
Tuple, Union
13+
Any, DefaultDict, Deque, Dict, List, Optional, Sequence, Tuple, Union
1514
)
1615

16+
from kitty.typing import (
17+
CompletedProcess, GRT_a, GRT_d, GRT_f, GRT_m, GRT_o, GRT_t, HandlerType,
18+
TypedDict
19+
)
1720
from kitty.utils import ScreenSize, fit_image
1821

1922
from .operations import cursor
@@ -25,28 +28,11 @@
2528
fsenc = 'utf-8'
2629

2730

28-
try:
29-
from typing import TypedDict, Literal
30-
GRT_a = Literal['t', 'T', 'q', 'p', 'd']
31-
GRT_f = Literal[24, 32, 100]
32-
GRT_t = Literal['d', 'f', 't', 's']
33-
GRT_o = Literal['z']
34-
GRT_m = Literal[0, 1]
35-
GRT_d = Literal['a', 'A', 'c', 'C', 'i', 'I', 'p', 'P', 'q', 'Q', 'x', 'X', 'y', 'Y', 'z', 'Z']
36-
except ImportError:
37-
TypedDict = dict
38-
39-
40-
if TYPE_CHECKING:
41-
import subprocess
42-
from .handler import Handler
43-
44-
4531
class ImageData:
4632

4733
def __init__(self, fmt: str, width: int, height: int, mode: str):
4834
self.width, self.height, self.fmt, self.mode = width, height, fmt, mode
49-
self.transmit_fmt: 'GRT_f' = (24 if self.mode == 'rgb' else 32)
35+
self.transmit_fmt: GRT_f = (24 if self.mode == 'rgb' else 32)
5036

5137

5238
class OpenFailed(ValueError):
@@ -71,7 +57,7 @@ class NoImageMagick(Exception):
7157
pass
7258

7359

74-
def run_imagemagick(path: str, cmd: Sequence[str], keep_stdout: bool = True) -> 'subprocess.CompletedProcess[bytes]':
60+
def run_imagemagick(path: str, cmd: Sequence[str], keep_stdout: bool = True) -> CompletedProcess:
7561
import subprocess
7662
try:
7763
p = subprocess.run(cmd, stdout=subprocess.PIPE if keep_stdout else subprocess.DEVNULL, stderr=subprocess.PIPE)
@@ -140,16 +126,16 @@ def can_display_images() -> bool:
140126

141127

142128
class GraphicsCommand:
143-
a: 'GRT_a' = 't' # action
144-
f: 'GRT_f' = 32 # image data format
145-
t: 'GRT_t' = 'd' # transmission medium
129+
a: GRT_a = 't' # action
130+
f: GRT_f = 32 # image data format
131+
t: GRT_t = 'd' # transmission medium
146132
s: int = 0 # sent image width
147133
v: int = 0 # sent image height
148134
S: int = 0 # size of data to read from file
149135
O: int = 0 # offset of data to read from file
150136
i: int = 0 # image id
151-
o: Optional['GRT_o'] = None # type of compression
152-
m: 'GRT_m' = 0 # 0 or 1 whether there is more chunked data
137+
o: Optional[GRT_o] = None # type of compression
138+
m: GRT_m = 0 # 0 or 1 whether there is more chunked data
153139
x: int = 0 # left edge of image area to display
154140
y: int = 0 # top edge of image area to display
155141
w: int = 0 # image width to display
@@ -159,7 +145,7 @@ class GraphicsCommand:
159145
c: int = 0 # number of cols to display image over
160146
r: int = 0 # number of rows to display image over
161147
z: int = 0 # z-index
162-
d: 'GRT_d' = 'a' # what to delete
148+
d: GRT_d = 'a' # what to delete
163149

164150
def serialize(self, payload: bytes = b'') -> bytes:
165151
items = []
@@ -193,7 +179,7 @@ class Placement(TypedDict):
193179

194180
class ImageManager:
195181

196-
def __init__(self, handler: 'Handler'):
182+
def __init__(self, handler: HandlerType):
197183
self.image_id_counter = count()
198184
self.handler = handler
199185
self.filesystem_ok: Optional[bool] = None

kittens/tui/loop.py

Lines changed: 6 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,7 @@
1212
import sys
1313
from contextlib import contextmanager
1414
from functools import partial
15-
from typing import (
16-
TYPE_CHECKING, Any, Callable, Dict, Generator, List, NamedTuple, Optional
17-
)
15+
from typing import Any, Callable, Dict, Generator, List, NamedTuple, Optional
1816

1917
from kitty.constants import is_macos
2018
from kitty.fast_data_types import (
@@ -24,20 +22,12 @@
2422
ALT, CTRL, PRESS, RELEASE, REPEAT, SHIFT, backspace_key, decode_key_event,
2523
enter_key, key_defs as K
2624
)
27-
from kitty.utils import screen_size_function, write_all
25+
from kitty.typing import ImageManagerType, KeyEventType, Protocol
26+
from kitty.utils import ScreenSizeGetter, screen_size_function, write_all
2827

2928
from .handler import Handler
3029
from .operations import init_state, reset_state
3130

32-
if TYPE_CHECKING:
33-
from kitty.key_encoding import KeyEvent
34-
from .images import ImageManager
35-
KeyEvent, ImageManager
36-
from typing import Protocol
37-
else:
38-
Protocol = object
39-
40-
4131
C, D = K['C'], K['D']
4232

4333

@@ -156,7 +146,7 @@ def initialize(self) -> None:
156146
self.write('\r\n')
157147
self.write('Press the Enter key to quit')
158148

159-
def on_key(self, key_event: 'KeyEvent') -> None:
149+
def on_key(self, key_event: KeyEventType) -> None:
160150
if key_event is enter_key:
161151
self.quit_loop(1)
162152

@@ -355,7 +345,7 @@ def quit(self, return_code: Optional[int] = None) -> None:
355345
self.return_code = return_code
356346
self.asycio_loop.stop()
357347

358-
def loop_impl(self, handler: Handler, term_manager: TermManager, image_manager: Optional['ImageManager'] = None) -> Optional[str]:
348+
def loop_impl(self, handler: Handler, term_manager: TermManager, image_manager: Optional[ImageManagerType] = None) -> Optional[str]:
359349
self.write_buf = []
360350
tty_fd = term_manager.tty_fd
361351
tb = None
@@ -399,7 +389,7 @@ def _on_sigwinch() -> None:
399389

400390
signal_manager = SignalManager(self.asycio_loop, _on_sigwinch, handler.on_interrupt, handler.on_term)
401391
with TermManager() as term_manager, signal_manager:
402-
self._get_screen_size = screen_size_function(term_manager.tty_fd)
392+
self._get_screen_size: ScreenSizeGetter = screen_size_function(term_manager.tty_fd)
403393
image_manager = None
404394
if handler.image_manager_class is not None:
405395
image_manager = handler.image_manager_class(handler)

0 commit comments

Comments
 (0)