From a26f0419645ef24f6899076f8d326d51c5eaffa0 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Wed, 27 Oct 2021 12:31:10 +0530 Subject: [PATCH] Add more type annotations --- kittens/diff/options/utils.py | 12 +++++++----- kittens/icat/main.py | 2 +- kittens/query_terminal/main.py | 2 +- kittens/themes/collection.py | 2 +- kitty/conf/utils.py | 33 ++++++++++++++++++--------------- kitty/debug_config.py | 10 +++++----- kitty/options/utils.py | 8 ++++---- kitty/rc/base.py | 2 +- kitty/remote_control.py | 6 +++--- kitty/update_check.py | 4 ++-- 10 files changed, 43 insertions(+), 38 deletions(-) diff --git a/kittens/diff/options/utils.py b/kittens/diff/options/utils.py index 3036f5d3e..0e88b3bc4 100644 --- a/kittens/diff/options/utils.py +++ b/kittens/diff/options/utils.py @@ -3,12 +3,14 @@ # License: GPLv3 Copyright: 2021, Kovid Goyal -from typing import Any, Dict, Iterable, Sequence, Tuple, Union +from typing import Any, Dict, Iterable, Tuple, Union -from kitty.conf.utils import KittensKeyDefinition, key_func, parse_kittens_key +from kitty.conf.utils import ( + KeyFuncWrapper, KittensKeyDefinition, parse_kittens_key +) -func_with_args, args_funcs = key_func() -FuncArgsType = Tuple[str, Sequence[Any]] +ReturnType = Tuple[str, Any] +func_with_args = KeyFuncWrapper[ReturnType]() @func_with_args('scroll_by') @@ -57,6 +59,6 @@ def syntax_aliases(raw: str) -> Dict[str, str]: def parse_map(val: str) -> Iterable[KittensKeyDefinition]: - x = parse_kittens_key(val, args_funcs) + x = parse_kittens_key(val, func_with_args.args_funcs) if x is not None: yield x diff --git a/kittens/icat/main.py b/kittens/icat/main.py index fbd494163..4af33c59e 100755 --- a/kittens/icat/main.py +++ b/kittens/icat/main.py @@ -447,7 +447,7 @@ def process_single_item( item: Union[bytes, str], args: IcatCLIOptions, parsed_opts: ParsedOpts, - url_pat: Optional[Pattern] = None, + url_pat: Optional['Pattern[str]'] = None, maybe_dir: bool = True ) -> None: is_tempfile = False diff --git a/kittens/query_terminal/main.py b/kittens/query_terminal/main.py index 86af00615..b7d518710 100644 --- a/kittens/query_terminal/main.py +++ b/kittens/query_terminal/main.py @@ -169,7 +169,7 @@ def get_result(name: str) -> Optional[str]: return q.get_result(get_options()) -def do_queries(queries: Iterable, cli_opts: QueryTerminalCLIOptions) -> Dict[str, str]: +def do_queries(queries: Iterable[str], cli_opts: QueryTerminalCLIOptions) -> Dict[str, str]: actions = tuple(all_queries[x]() for x in queries) qstring = ''.join(a.query_code() for a in actions) received = b'' diff --git a/kittens/themes/collection.py b/kittens/themes/collection.py index 6416af6e7..b92f58c33 100644 --- a/kittens/themes/collection.py +++ b/kittens/themes/collection.py @@ -149,7 +149,7 @@ def theme_name_from_file_name(fname: str) -> str: ans = fname.rsplit('.', 1)[0] ans = ans.replace('_', ' ') - def camel_case(m: Match) -> str: + def camel_case(m: 'Match[str]') -> str: return str(m.group(1) + ' ' + m.group(2)) ans = re.sub(r'([a-z])([A-Z])', camel_case, ans) diff --git a/kitty/conf/utils.py b/kitty/conf/utils.py index 7d22c62ac..d6b93b57e 100644 --- a/kitty/conf/utils.py +++ b/kitty/conf/utils.py @@ -6,7 +6,7 @@ import re import shlex from typing import ( Any, Callable, Dict, Generator, Iterable, List, NamedTuple, Optional, - Sequence, Set, Tuple, TypeVar, Union + Sequence, Set, Tuple, TypeVar, Union, Generic ) from ..rgb import Color, to_color as as_color @@ -188,7 +188,7 @@ def parse_config_base( ) -def merge_dicts(defaults: Dict, newvals: Dict) -> Dict: +def merge_dicts(defaults: Dict[str, Any], newvals: Dict[str, Any]) -> Dict[str, Any]: ans = defaults.copy() ans.update(newvals) return ans @@ -207,7 +207,7 @@ def resolve_config(SYSTEM_CONF: str, defconf: str, config_files_on_cmd_line: Seq def load_config( defaults: OptionsProtocol, parse_config: Callable[[Iterable[str]], Dict[str, Any]], - merge_configs: Callable[[Dict, Dict], Dict], + merge_configs: Callable[[Dict[str, Any], Dict[str, Any]], Dict[str, Any]], *paths: str, overrides: Optional[Iterable[str]] = None ) -> Tuple[Dict[str, Any], Tuple[str, ...]]: @@ -229,22 +229,25 @@ def load_config( return ans, tuple(found_paths) -def key_func() -> Tuple[Callable[..., Callable], Dict[str, Callable]]: - ans: Dict[str, Callable] = {} +ReturnType = TypeVar('ReturnType') +KeyFunc = Callable[[str, str], ReturnType] - def func_with_args(*names: str) -> Callable: - def w(f: Callable) -> Callable: +class KeyFuncWrapper(Generic[ReturnType]): + def __init__(self) -> None: + self.args_funcs: Dict[str, KeyFunc[ReturnType]] = {} + + def __call__(self, *names: str) -> Callable[[KeyFunc[ReturnType]], KeyFunc[ReturnType]]: + + def w(f: KeyFunc[ReturnType]) -> KeyFunc[ReturnType]: for name in names: - if ans.setdefault(name, f) is not f: - raise ValueError( - f'the args_func {name} is being redefined' - ) + if self.args_funcs.setdefault(name, f) is not f: + raise ValueError(f'the args_func {name} is being redefined') return f - return w - return func_with_args, ans + def get(self, name: str) -> Optional[KeyFunc[ReturnType]]: + return self.args_funcs.get(name) class KeyAction(NamedTuple): @@ -257,7 +260,7 @@ class KeyAction(NamedTuple): return f'KeyAction({self.func!r})' -def parse_kittens_func_args(action: str, args_funcs: Dict[str, Callable]) -> KeyAction: +def parse_kittens_func_args(action: str, args_funcs: Dict[str, KeyFunc[Tuple[str, Any]]]) -> KeyAction: parts = action.strip().split(' ', 1) func = parts[0] if len(parts) == 1: @@ -288,7 +291,7 @@ KittensKeyMap = Dict[ParsedShortcut, KeyAction] def parse_kittens_key( - val: str, funcs_with_args: Dict[str, Callable] + val: str, funcs_with_args: Dict[str, KeyFunc[Tuple[str, Any]]] ) -> Optional[KittensKeyDefinition]: from ..key_encoding import parse_shortcut sc, action = val.partition(' ')[::2] diff --git a/kitty/debug_config.py b/kitty/debug_config.py index 68f3a4ad0..943405d1b 100644 --- a/kitty/debug_config.py +++ b/kitty/debug_config.py @@ -54,7 +54,7 @@ def mod_to_names(mods: int) -> Generator[str, None, None]: yield name -def print_shortcut(key_sequence: Iterable[SingleKey], action: KeyAction, print: Callable) -> None: +def print_shortcut(key_sequence: Iterable[SingleKey], action: KeyAction, print: Callable[..., None]) -> None: from .fast_data_types import glfw_get_key_name keys = [] for key_spec in key_sequence: @@ -69,7 +69,7 @@ def print_shortcut(key_sequence: Iterable[SingleKey], action: KeyAction, print: print('\t' + ' > '.join(keys), action) -def print_shortcut_changes(defns: ShortcutMap, text: str, changes: Set[Tuple[SingleKey, ...]], print: Callable) -> None: +def print_shortcut_changes(defns: ShortcutMap, text: str, changes: Set[Tuple[SingleKey, ...]], print: Callable[..., None]) -> None: if changes: print(title(text)) @@ -77,7 +77,7 @@ def print_shortcut_changes(defns: ShortcutMap, text: str, changes: Set[Tuple[Sin print_shortcut(k, defns[k], print) -def compare_keymaps(final: ShortcutMap, initial: ShortcutMap, print: Callable) -> None: +def compare_keymaps(final: ShortcutMap, initial: ShortcutMap, print: Callable[..., None]) -> None: added = set(final) - set(initial) removed = set(initial) - set(final) changed = {k for k in set(final) & set(initial) if final[k] != initial[k]} @@ -94,7 +94,7 @@ def flatten_sequence_map(m: SequenceMap) -> ShortcutMap: return ans -def compare_mousemaps(final: MouseMap, initial: MouseMap, print: Callable) -> None: +def compare_mousemaps(final: MouseMap, initial: MouseMap, print: Callable[..., None]) -> None: added = set(final) - set(initial) removed = set(initial) - set(final) changed = {k for k in set(final) & set(initial) if final[k] != initial[k]} @@ -116,7 +116,7 @@ def compare_mousemaps(final: MouseMap, initial: MouseMap, print: Callable) -> No print_changes(final, changed, 'Changed mouse actions:') -def compare_opts(opts: KittyOpts, print: Callable) -> None: +def compare_opts(opts: KittyOpts, print: Callable[..., None]) -> None: from .config import load_config print() print('Config options different from defaults:') diff --git a/kitty/options/utils.py b/kitty/options/utils.py index 8ab5ca5e6..9823f8b72 100644 --- a/kitty/options/utils.py +++ b/kitty/options/utils.py @@ -12,8 +12,8 @@ from typing import ( import kitty.fast_data_types as defines from kitty.conf.utils import ( - KeyAction, key_func, positive_float, positive_int, python_string, to_bool, - to_cmdline, to_color, uniq, unit_float + KeyAction, KeyFuncWrapper, positive_float, positive_int, + python_string, to_bool, to_cmdline, to_color, uniq, unit_float ) from kitty.constants import config_dir, is_macos from kitty.fast_data_types import CURSOR_BEAM, CURSOR_BLOCK, CURSOR_UNDERLINE @@ -39,8 +39,8 @@ character_key_name_aliases_with_ascii_lowercase: Dict[str, str] = character_key_ for x in 'ABCDEFGHIJKLMNOPQRSTUVWXYZ': character_key_name_aliases_with_ascii_lowercase[x] = x.lower() sequence_sep = '>' -func_with_args, args_funcs = key_func() FuncArgsType = Tuple[str, Sequence[Any]] +func_with_args = KeyFuncWrapper[FuncArgsType]() DELETE_ENV_VAR = '_delete_this_env_var_' @@ -794,7 +794,7 @@ def parse_key_action(action: str, action_type: str = 'map') -> Optional[KeyActio if len(parts) == 1: return KeyAction(func, ()) rest = parts[1] - parser = args_funcs.get(func) + parser = func_with_args.get(func) if parser is not None: try: func, args = parser(func, rest) diff --git a/kitty/rc/base.py b/kitty/rc/base.py index e8f6f8edf..c9711fc2e 100644 --- a/kitty/rc/base.py +++ b/kitty/rc/base.py @@ -64,7 +64,7 @@ class PayloadGetter: no_response = NoResponse() payload_get = object() -ResponseType = Union[bool, str, None] +ResponseType = Union[bool, str, None, NoResponse] CmdReturnType = Union[Dict[str, Any], List[Any], Tuple[Any, ...], str, int, float, bool] CmdGenerator = Iterator[CmdReturnType] PayloadType = Optional[Union[CmdReturnType, CmdGenerator]] diff --git a/kitty/remote_control.py b/kitty/remote_control.py index f15fe0401..fdc931c03 100644 --- a/kitty/remote_control.py +++ b/kitty/remote_control.py @@ -18,7 +18,7 @@ from .constants import appname, version from .fast_data_types import read_command_response from .rc.base import ( ParsingOfArgsFailed, PayloadGetter, all_command_names, command_for_name, - no_response as no_response_sentinel, parse_subcommand_cli + NoResponse, parse_subcommand_cli ) from .typing import BossType, WindowType from .utils import TTYIO, parse_address_spec @@ -41,7 +41,7 @@ def handle_cmd(boss: BossType, window: Optional[WindowType], serialized_cmd: str if no_response: # don't report errors if --no-response was used return None raise - if ans is no_response_sentinel: + if isinstance(ans, NoResponse): return None response: Dict[str, Any] = {'ok': True} if ans is not None: @@ -114,7 +114,7 @@ class RCIO(TTYIO): return b''.join(ans) -def do_io(to: Optional[str], send: Dict, no_response: bool) -> Dict[str, Any]: +def do_io(to: Optional[str], send: Dict[str, Any], no_response: bool) -> Dict[str, Any]: payload = send.get('payload') if not isinstance(payload, types.GeneratorType): send_data: Union[bytes, Iterable[bytes]] = encode_send(send) diff --git a/kitty/update_check.py b/kitty/update_check.py index 0bf6c4626..e61d78c54 100644 --- a/kitty/update_check.py +++ b/kitty/update_check.py @@ -5,7 +5,7 @@ import os import subprocess import time from contextlib import suppress -from typing import Dict, NamedTuple, Optional +from typing import Dict, NamedTuple, Optional, Tuple from urllib.request import urlopen from .config import atomic_save @@ -73,7 +73,7 @@ def read_cache() -> Dict[Version, Notification]: return notified_versions -def already_notified(version: tuple) -> bool: +def already_notified(version: Tuple[int, int, int]) -> bool: notified_versions = read_cache() return version in notified_versions