From b22bda3cbaf00508fcb37e01c97c7a7ee3202718 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Wed, 27 Oct 2021 11:36:34 +0530 Subject: [PATCH] Add more type annotations --- kittens/diff/highlight.py | 2 +- kittens/panel/main.py | 8 ++++---- kittens/ssh/completion.py | 2 +- kittens/transfer/receive.py | 2 +- kittens/transfer/utils.py | 5 ++--- kitty/actions.py | 20 ++++++++++++-------- kitty/complete.py | 6 +++--- kitty/conf/types.py | 23 ++++++++++++----------- kitty/file_transmission.py | 4 ++-- kitty/main.py | 8 +++++--- kitty/multiprocessing.py | 2 +- kitty/os_window_size.py | 2 +- 12 files changed, 45 insertions(+), 39 deletions(-) diff --git a/kittens/diff/highlight.py b/kittens/diff/highlight.py index 6a3ce3ece..0e13407fb 100644 --- a/kittens/diff/highlight.py +++ b/kittens/diff/highlight.py @@ -21,7 +21,7 @@ class StyleNotFound(Exception): pass -class DiffFormatter(Formatter): +class DiffFormatter(Formatter): # type: ignore def __init__(self, style: str = 'default') -> None: try: diff --git a/kittens/panel/main.py b/kittens/panel/main.py index 19c89b835..61f90ce46 100644 --- a/kittens/panel/main.py +++ b/kittens/panel/main.py @@ -5,11 +5,11 @@ import os import shutil import subprocess import sys -from typing import Callable, Dict, List, Tuple +from typing import Any, Callable, Dict, List, Tuple from kitty.cli import parse_args from kitty.cli_stub import PanelCLIOptions -from kitty.constants import is_macos, appname +from kitty.constants import appname, is_macos from kitty.os_window_size import WindowSizeData OPTIONS = r''' @@ -119,7 +119,7 @@ def setup_x11_window(win_id: int) -> None: func(win_id, window_width, window_height) -def initial_window_size_func(opts: WindowSizeData, cached_values: Dict) -> Callable[[int, int, float, float, float, float], Tuple[int, int]]: +def initial_window_size_func(opts: WindowSizeData, cached_values: Dict[str, Any]) -> Callable[[int, int, float, float, float, float], Tuple[int, int]]: from kitty.fast_data_types import glfw_primary_monitor_size def initial_window_size(cell_width: int, cell_height: int, dpi_x: float, dpi_y: float, xscale: float, yscale: float) -> Tuple[int, int]: @@ -154,7 +154,7 @@ def main(sys_args: List[str]) -> None: for override in args.override: sys.argv.extend(('--override', override)) sys.argv.extend(items) - from kitty.main import run_app, main as real_main + from kitty.main import main as real_main, run_app run_app.cached_values_name = 'panel' run_app.first_window_callback = setup_x11_window run_app.initial_window_size_func = initial_window_size_func diff --git a/kittens/ssh/completion.py b/kittens/ssh/completion.py index b6d0ed4dd..ff97c6bd9 100644 --- a/kittens/ssh/completion.py +++ b/kittens/ssh/completion.py @@ -295,7 +295,7 @@ def complete_q_choices(ans: Completions, prefix: str, title: str, key: str, comm def complete_arg(ans: Completions, option_flag: str, prefix: str = '') -> None: options = ssh_options() option_name = options.get(option_flag[1:]) - if option_name.endswith('file') or option_name.endswith('path'): + if option_name and (option_name.endswith('file') or option_name.endswith('path')): return complete_files_and_dirs(ans, prefix, option_name) choices = { 'mac_spec': ('MAC algorithm', 'mac', True), diff --git a/kittens/transfer/receive.py b/kittens/transfer/receive.py index 10fc49dbc..b7a3432c0 100644 --- a/kittens/transfer/receive.py +++ b/kittens/transfer/receive.py @@ -146,7 +146,7 @@ class Manager: self.failed_specs[fid] = ftc.status else: if ftc.status == 'OK': - self.state == State.transferring + self.state = State.transferring return '' else: return ftc.status diff --git a/kittens/transfer/utils.py b/kittens/transfer/utils.py index 20d3d992a..c410d7c29 100644 --- a/kittens/transfer/utils.py +++ b/kittens/transfer/utils.py @@ -5,7 +5,7 @@ import os from contextlib import contextmanager from datetime import timedelta from mimetypes import guess_type -from typing import Callable, Generator, Union, cast +from typing import Callable, Generator, Union from kitty.fast_data_types import truncate_point_for_length, wcswidth from kitty.types import run_once @@ -154,8 +154,7 @@ def short_uuid_func() -> Callable[[], str]: def random_id() -> str: - f = short_uuid_func() - return cast(str, f()) + return short_uuid_func()() @contextmanager diff --git a/kitty/actions.py b/kitty/actions.py index 780ca35c6..5cb5837af 100644 --- a/kitty/actions.py +++ b/kitty/actions.py @@ -2,17 +2,17 @@ # License: GPLv3 Copyright: 2021, Kovid Goyal import inspect -from typing import Dict, List, NamedTuple +from typing import Dict, List, NamedTuple, cast from .boss import Boss from .tabs import Tab -from .types import run_once, ActionGroup, ActionSpec +from .types import ActionGroup, ActionSpec, run_once from .window import Window class Action(NamedTuple): name: str - group: str + group: ActionGroup short_help: str long_help: str @@ -32,10 +32,10 @@ group_title = groups.__getitem__ @run_once -def get_all_actions() -> Dict[str, List[Action]]: +def get_all_actions() -> Dict[ActionGroup, List[Action]]: ' test docstring ' - ans: Dict[str, List[Action]] = {} + ans: Dict[ActionGroup, List[Action]] = {} def is_action(x: object) -> bool: return isinstance(getattr(x, 'action_spec', None), ActionSpec) @@ -47,7 +47,8 @@ def get_all_actions() -> Dict[str, List[Action]]: first = lines.pop(0) short_help = first long_help = '\n'.join(lines).strip() - return Action(getattr(x, '__name__'), spec.group, short_help, long_help) + assert spec.group in groups + return Action(getattr(x, '__name__'), cast(ActionGroup, spec.group), short_help, long_help) seen = set() for cls in (Window, Tab, Boss): @@ -74,8 +75,8 @@ def dump() -> None: def as_rst() -> str: - from .options.definition import definition from .conf.types import Mapping + from .options.definition import definition allg = get_all_actions() lines: List[str] = [] a = lines.append @@ -85,7 +86,10 @@ def as_rst() -> str: func = m.action_def.split()[0] maps.setdefault(func, []).append(m) - for group in sorted(allg, key=lambda x: group_title(x).lower()): + def key(x: ActionGroup) -> str: + return group_title(x).lower() + + for group in sorted(allg, key=key): title = group_title(group) a('') a(f'.. _action-group-{group}:') diff --git a/kitty/complete.py b/kitty/complete.py index f37025002..db3d9c634 100644 --- a/kitty/complete.py +++ b/kitty/complete.py @@ -42,8 +42,8 @@ taking the results from kitty's completion system and converting them into something your shell will understand. ''' -parsers: Dict[str, Callable] = {} -serializers: Dict[str, Callable] = {} +parsers: Dict[str, 'ParserFunc'] = {} +serializers: Dict[str, 'SerializerFunc'] = {} class MatchGroup: @@ -469,7 +469,7 @@ def path_completion(prefix: str = '') -> Tuple[List[str], List[str]]: src = os.path.expandvars(os.path.expanduser(base)) src_prefix = os.path.abspath(os.path.expandvars(os.path.expanduser(prefix))) if prefix else '' try: - items: Iterable[os.DirEntry] = os.scandir(src) + items: Iterable['os.DirEntry[str]'] = os.scandir(src) except FileNotFoundError: items = () for x in items: diff --git a/kitty/conf/types.py b/kitty/conf/types.py index 1bf697446..8af3e98fc 100644 --- a/kitty/conf/types.py +++ b/kitty/conf/types.py @@ -25,12 +25,13 @@ class Unset: unset = Unset() +ParserFuncType = Callable[[str], Any] def expand_opt_references(conf_name: str, text: str) -> str: conf_name += '.' - def expand(m: Match) -> str: + def expand(m: 'Match[str]') -> str: ref = m.group(1) if '<' not in ref and '.' not in ref: full_ref = conf_name + ref @@ -50,7 +51,7 @@ def remove_markup(text: str) -> str: 'shell_integration': website_url("shell-integration"), } - def sub(m: Match) -> str: + def sub(m: 'Match[str]') -> str: if m.group(1) == 'ref': return ref_map[m.group(2)] return str(m.group(2)) @@ -152,7 +153,7 @@ class CoalescedIteratorData: class Option: def __init__( - self, name: str, defval: str, macos_default: Union[Unset, str], parser_func: Callable, + self, name: str, defval: str, macos_default: Union[Unset, str], parser_func: ParserFuncType, long_text: str, documented: bool, group: 'Group', choices: Tuple[str, ...], ctype: str ): self.name = name @@ -224,7 +225,7 @@ class MultiVal: class MultiOption: - def __init__(self, name: str, parser_func: Callable, long_text: str, group: 'Group', ctype: str): + def __init__(self, name: str, parser_func: ParserFuncType, long_text: str, group: 'Group', ctype: str): self.name = name self.ctype = ctype self.parser_func = parser_func @@ -513,7 +514,7 @@ class Group: return ans -def resolve_import(name: str, module: Any = None) -> Callable: +def resolve_import(name: str, module: Any = None) -> ParserFuncType: ans = None if name.count('.') > 1: m = import_module(name.rpartition('.')[0]) @@ -526,7 +527,7 @@ def resolve_import(name: str, module: Any = None) -> Callable: ans = getattr(module, name) if not callable(ans): raise TypeError(f'{name} is not a function') - return cast(Callable, ans) + return cast(ParserFuncType, ans) class Action: @@ -558,7 +559,7 @@ class Definition: self.shortcut_map: Dict[str, List[ShortcutMapping]] = {} self.mouse_map: Dict[str, List[MouseMapping]] = {} self.actions = {a.name: a.resolve_imports(self.module_for_parsers) for a in actions} - self.deprecations: Dict[Callable, Tuple[str, ...]] = {} + self.deprecations: Dict[ParserFuncType, Tuple[str, ...]] = {} def iter_all_non_groups(self) -> Iterator[NonGroups]: yield from self.root_group.iter_all_non_groups() @@ -575,17 +576,17 @@ class Definition: elif isinstance(x, MouseMapping) and which in ('mouse_map', '*'): yield x - def parser_func(self, name: str) -> Callable: + def parser_func(self, name: str) -> ParserFuncType: ans = getattr(builtins, name, None) if callable(ans): - return cast(Callable, ans) + return cast(ParserFuncType, ans) ans = getattr(generic_parsers, name, None) if callable(ans): - return cast(Callable, ans) + return cast(ParserFuncType, ans) ans = getattr(self.module_for_parsers, name) if not callable(ans): raise TypeError(f'{name} is not a function') - return cast(Callable, ans) + return cast(ParserFuncType, ans) def add_group(self, name: str, title: str = '', start_text: str = '') -> None: self.current_group = Group(name, title or name, self.coalesced_iterator_data, start_text.strip(), self.current_group) diff --git a/kitty/file_transmission.py b/kitty/file_transmission.py index c56eb21d6..6c78be9dc 100644 --- a/kitty/file_transmission.py +++ b/kitty/file_transmission.py @@ -296,7 +296,7 @@ class FileTransmissionCommand: @classmethod def deserialize(cls, data: Union[str, bytes, memoryview]) -> 'FileTransmissionCommand': ans = FileTransmissionCommand() - fmap: Dict[bytes, Field] = getattr(cls, 'fmap', None) + fmap: Dict[bytes, 'Field[Union[str, int, bytes, Enum]]'] = getattr(cls, 'fmap', None) if not fmap: fmap = {k.name.encode('ascii'): k for k in fields(cls)} setattr(cls, 'fmap', fmap) @@ -936,7 +936,7 @@ class TestFileTransmission(FileTransmission): def __init__(self, allow: bool = True) -> None: super().__init__(0) - self.test_responses: List[dict] = [] + self.test_responses: List[Dict[str, Union[str, int, bytes]]] = [] self.allow = allow def write_ftc_to_child(self, payload: FileTransmissionCommand, appendleft: bool = False, use_pending: bool = True) -> bool: diff --git a/kitty/main.py b/kitty/main.py index d7a19c6f7..978f1e802 100644 --- a/kitty/main.py +++ b/kitty/main.py @@ -6,7 +6,7 @@ import os import shutil import sys from contextlib import contextmanager, suppress -from typing import Dict, Generator, List, Optional, Sequence, Tuple +from typing import Any, Dict, Generator, List, Optional, Sequence, Tuple from .borders import load_borders_program from .boss import Boss @@ -103,7 +103,7 @@ def init_glfw(opts: Options, debug_keyboard: bool = False, debug_rendering: bool return glfw_module -def get_macos_shortcut_for(opts: Options, function: str = 'new_os_window', args: Tuple = (), lookup_name: str = '') -> Optional[SingleKey]: +def get_macos_shortcut_for(opts: Options, function: str = 'new_os_window', args: Tuple[Any, ...] = (), lookup_name: str = '') -> Optional[SingleKey]: ans = None candidates = [] for k, v in opts.keymap.items(): @@ -187,7 +187,9 @@ class AppRunner: set_options(None) free_font_data() # must free font data before glfw/freetype/fontconfig/opengl etc are finalized if is_macos: - from kitty.fast_data_types import cocoa_set_notification_activated_callback + from kitty.fast_data_types import ( + cocoa_set_notification_activated_callback + ) cocoa_set_notification_activated_callback(None) diff --git a/kitty/multiprocessing.py b/kitty/multiprocessing.py index f0717ab9a..dda1b677d 100644 --- a/kitty/multiprocessing.py +++ b/kitty/multiprocessing.py @@ -42,7 +42,7 @@ def unmonkey_patch_multiprocessing() -> None: def get_process_pool_executor( prefer_fork: bool = False, max_workers: Optional[int] = None, - initializer: Optional[Callable] = None, + initializer: Optional[Callable[..., None]] = None, initargs: Tuple[Any, ...] = () ) -> ProcessPoolExecutor: if prefer_fork and 'fork' in get_all_start_methods(): diff --git a/kitty/os_window_size.py b/kitty/os_window_size.py index c7b48d676..bcdd9d559 100644 --- a/kitty/os_window_size.py +++ b/kitty/os_window_size.py @@ -29,7 +29,7 @@ class WindowSizeData(NamedTuple): window_padding_width: FloatEdges -def initial_window_size_func(opts: WindowSizeData, cached_values: Dict) -> Callable[[int, int, float, float, float, float], Tuple[int, int]]: +def initial_window_size_func(opts: WindowSizeData, cached_values: Dict[str, Any]) -> Callable[[int, int, float, float, float, float], Tuple[int, int]]: if 'window-size' in cached_values and opts.remember_window_size: ws = cached_values['window-size']