More typing work
This commit is contained in:
parent
abff2292c1
commit
8ae110691e
@ -6,14 +6,14 @@
|
||||
# Utils {{{
|
||||
from functools import partial
|
||||
from gettext import gettext as _
|
||||
from typing import Any, Dict, Union
|
||||
from typing import Any, Dict, Sequence, Union
|
||||
|
||||
from kitty.conf.definition import Option, Shortcut, option_func
|
||||
from kitty.conf.utils import positive_int, python_string, to_color
|
||||
|
||||
# }}}
|
||||
|
||||
all_options: Dict[str, Union[Option, Shortcut]] = {}
|
||||
all_options: Dict[str, Union[Option, Sequence[Shortcut]]] = {}
|
||||
o, k, g, all_groups = option_func(all_options, {
|
||||
'colors': [_('Colors')],
|
||||
'diff': [_('Diffing'), ],
|
||||
|
||||
@ -5,7 +5,8 @@
|
||||
import re
|
||||
from functools import partial
|
||||
from typing import (
|
||||
Any, Dict, Iterable, List, Optional, Set, Tuple, Union, get_type_hints
|
||||
Any, Callable, Dict, Generator, Iterable, List, Match, Optional, Sequence,
|
||||
Set, Tuple, Union, cast, get_type_hints
|
||||
)
|
||||
|
||||
from .utils import to_bool
|
||||
@ -19,7 +20,7 @@ class Group:
|
||||
|
||||
__slots__ = 'name', 'short_text', 'start_text', 'end_text'
|
||||
|
||||
def __init__(self, name, short_text, start_text='', end_text=''):
|
||||
def __init__(self, name: str, short_text: str, start_text: str = '', end_text: str = '') -> None:
|
||||
self.name, self.short_text = name, short_text.strip()
|
||||
self.start_text, self.end_text = start_text.strip(), end_text.strip()
|
||||
|
||||
@ -28,7 +29,7 @@ class Option:
|
||||
|
||||
__slots__ = 'name', 'group', 'long_text', 'option_type', 'defval_as_string', 'add_to_default', 'add_to_docs', 'line'
|
||||
|
||||
def __init__(self, name: str, group: str, defval: str, option_type: Any, long_text: str, add_to_default: bool, add_to_docs: bool):
|
||||
def __init__(self, name: str, group: Group, defval: str, option_type: Any, long_text: str, add_to_default: bool, add_to_docs: bool):
|
||||
self.name, self.group = name, group
|
||||
self.long_text, self.option_type = long_text.strip(), option_type
|
||||
self.defval_as_string = defval
|
||||
@ -67,7 +68,7 @@ class Shortcut:
|
||||
|
||||
__slots__ = 'name', 'group', 'key', 'action_def', 'short_text', 'long_text', 'add_to_default', 'add_to_docs', 'line'
|
||||
|
||||
def __init__(self, name, group, key, action_def, short_text, long_text, add_to_default, add_to_docs):
|
||||
def __init__(self, name: str, group: Group, key: str, action_def: str, short_text: str, long_text: str, add_to_default: bool, add_to_docs: bool):
|
||||
self.name, self.group, self.key, self.action_def = name, group, key, action_def
|
||||
self.short_text, self.long_text = short_text, long_text
|
||||
self.add_to_default = add_to_default
|
||||
@ -76,15 +77,15 @@ class Shortcut:
|
||||
|
||||
|
||||
def option(
|
||||
all_options,
|
||||
group,
|
||||
name,
|
||||
defval,
|
||||
long_text='',
|
||||
option_type=to_string,
|
||||
add_to_default=True,
|
||||
add_to_docs=True
|
||||
):
|
||||
all_options: Dict[str, Option],
|
||||
group: Sequence[Group],
|
||||
name: str,
|
||||
defval: Any,
|
||||
long_text: str = '',
|
||||
option_type: Callable[[str], Any] = to_string,
|
||||
add_to_default: bool = True,
|
||||
add_to_docs: bool = True
|
||||
) -> Option:
|
||||
is_multiple = name.startswith('+')
|
||||
if is_multiple:
|
||||
name = name[1:]
|
||||
@ -109,33 +110,33 @@ def option(
|
||||
|
||||
|
||||
def shortcut(
|
||||
all_options,
|
||||
group,
|
||||
action_name,
|
||||
key,
|
||||
action_def,
|
||||
short_text='',
|
||||
long_text='',
|
||||
add_to_default=True,
|
||||
add_to_docs=True
|
||||
):
|
||||
all_options: Dict[str, List[Shortcut]],
|
||||
group: Sequence[Group],
|
||||
action_name: str,
|
||||
key: str,
|
||||
action_def: str,
|
||||
short_text: str = '',
|
||||
long_text: str = '',
|
||||
add_to_default: bool = True,
|
||||
add_to_docs: bool = True
|
||||
) -> Shortcut:
|
||||
ans = Shortcut(action_name, group[0], key, action_def, short_text, long_text, add_to_default, add_to_docs)
|
||||
key = 'sc-' + action_name
|
||||
all_options.setdefault(key, []).append(ans)
|
||||
return ans
|
||||
|
||||
|
||||
def option_func(all_options, all_groups):
|
||||
all_groups = {k: Group(k, *v) for k, v in all_groups.items()}
|
||||
group = [None]
|
||||
def option_func(all_options: Dict[str, Any], all_groups: Dict[str, Sequence[str]]) -> Tuple[Callable, Callable, Callable[[str], None], Dict[str, Group]]:
|
||||
all_groups_ = {k: Group(k, *v) for k, v in all_groups.items()}
|
||||
group: List[Optional[Group]] = [None]
|
||||
|
||||
def change_group(name):
|
||||
group[0] = all_groups[name]
|
||||
def change_group(name: str) -> None:
|
||||
group[0] = all_groups_[name]
|
||||
|
||||
return partial(option, all_options, group), partial(shortcut, all_options, group), change_group, all_groups
|
||||
return partial(option, all_options, group), partial(shortcut, all_options, group), change_group, all_groups_
|
||||
|
||||
|
||||
def merged_opts(all_options, opt, i):
|
||||
def merged_opts(all_options: Sequence[Union[Option, Sequence[Shortcut]]], opt: Option, i: int) -> Generator[Option, None, None]:
|
||||
yield opt
|
||||
for k in range(i + 1, len(all_options)):
|
||||
q = all_options[k]
|
||||
@ -147,20 +148,20 @@ def merged_opts(all_options, opt, i):
|
||||
break
|
||||
|
||||
|
||||
def remove_markup(text):
|
||||
def remove_markup(text: str) -> str:
|
||||
|
||||
def sub(m):
|
||||
def sub(m: Match) -> str:
|
||||
if m.group(1) == 'ref':
|
||||
return {
|
||||
'layouts': 'https://sw.kovidgoyal.net/kitty/index.html#layouts',
|
||||
'sessions': 'https://sw.kovidgoyal.net/kitty/index.html#sessions',
|
||||
}[m.group(2)]
|
||||
return m.group(2)
|
||||
return cast(str, m.group(2))
|
||||
|
||||
return re.sub(r':([a-zA-Z0-9]+):`(.+?)`', sub, text, flags=re.DOTALL)
|
||||
|
||||
|
||||
def iter_blocks(lines: Iterable[str]):
|
||||
def iter_blocks(lines: Iterable[str]) -> Generator[Tuple[List[str], int], None, None]:
|
||||
current_block: List[str] = []
|
||||
prev_indent = 0
|
||||
for line in lines:
|
||||
@ -178,7 +179,7 @@ def iter_blocks(lines: Iterable[str]):
|
||||
yield current_block, indent_size
|
||||
|
||||
|
||||
def wrapped_block(lines):
|
||||
def wrapped_block(lines: Iterable[str]) -> Generator[str, None, None]:
|
||||
wrapper = getattr(wrapped_block, 'wrapper', None)
|
||||
if wrapper is None:
|
||||
import textwrap
|
||||
@ -198,20 +199,20 @@ def wrapped_block(lines):
|
||||
yield line
|
||||
|
||||
|
||||
def render_block(text):
|
||||
def render_block(text: str) -> str:
|
||||
text = remove_markup(text)
|
||||
lines = text.splitlines()
|
||||
return '\n'.join(wrapped_block(lines))
|
||||
|
||||
|
||||
def as_conf_file(all_options: Iterable[Union[Option, Shortcut]]) -> List[str]:
|
||||
def as_conf_file(all_options: Iterable[Union[Option, Sequence[Shortcut]]]) -> List[str]:
|
||||
ans = ['# vim:fileencoding=utf-8:ft=conf:foldmethod=marker', '']
|
||||
a = ans.append
|
||||
current_group: Optional[Group] = None
|
||||
num_open_folds = 0
|
||||
all_options = list(all_options)
|
||||
all_options_ = list(all_options)
|
||||
|
||||
def render_group(group, is_shortcut):
|
||||
def render_group(group: Group, is_shortcut: bool) -> None:
|
||||
nonlocal num_open_folds
|
||||
if is_shortcut or '.' not in group.name:
|
||||
a('#: ' + group.short_text + ' {{''{')
|
||||
@ -221,7 +222,7 @@ def as_conf_file(all_options: Iterable[Union[Option, Shortcut]]) -> List[str]:
|
||||
a(render_block(group.start_text))
|
||||
a('')
|
||||
|
||||
def handle_group_end(group, new_group_name='', new_group_is_shortcut=False):
|
||||
def handle_group_end(group: Group, new_group_name: str = '', new_group_is_shortcut: bool = False) -> None:
|
||||
nonlocal num_open_folds
|
||||
if group.end_text:
|
||||
a(''), a(render_block(group.end_text))
|
||||
@ -230,7 +231,7 @@ def as_conf_file(all_options: Iterable[Union[Option, Shortcut]]) -> List[str]:
|
||||
a('#: }}''}'), a('')
|
||||
num_open_folds -= 1
|
||||
|
||||
def handle_group(new_group, is_shortcut=False):
|
||||
def handle_group(new_group: Group, is_shortcut: bool = False) -> None:
|
||||
nonlocal current_group
|
||||
if new_group is not current_group:
|
||||
if current_group:
|
||||
@ -238,7 +239,7 @@ def as_conf_file(all_options: Iterable[Union[Option, Shortcut]]) -> List[str]:
|
||||
current_group = new_group
|
||||
render_group(current_group, is_shortcut)
|
||||
|
||||
def handle_shortcut(shortcuts):
|
||||
def handle_shortcut(shortcuts: Sequence[Shortcut]) -> None:
|
||||
handle_group(shortcuts[0].group, True)
|
||||
for sc in shortcuts:
|
||||
if sc.add_to_default:
|
||||
@ -246,11 +247,11 @@ def as_conf_file(all_options: Iterable[Union[Option, Shortcut]]) -> List[str]:
|
||||
if sc.long_text:
|
||||
a(''), a(render_block(sc.long_text.strip())), a('')
|
||||
|
||||
def handle_option(opt):
|
||||
def handle_option(opt: Option) -> None:
|
||||
if not opt.long_text or not opt.add_to_docs:
|
||||
return
|
||||
handle_group(opt.group)
|
||||
mopts = list(merged_opts(all_options, opt, i))
|
||||
mopts = list(merged_opts(all_options_, opt, i))
|
||||
sz = max(len(x.name) for x in mopts)
|
||||
for mo in mopts:
|
||||
prefix = '' if mo.add_to_default else '# '
|
||||
@ -259,7 +260,7 @@ def as_conf_file(all_options: Iterable[Union[Option, Shortcut]]) -> List[str]:
|
||||
a(render_block(opt.long_text))
|
||||
a('')
|
||||
|
||||
for i, opt in enumerate(all_options):
|
||||
for i, opt in enumerate(all_options_):
|
||||
if isinstance(opt, Option):
|
||||
handle_option(opt)
|
||||
else:
|
||||
@ -298,7 +299,9 @@ def as_conf_file(all_options: Iterable[Union[Option, Shortcut]]) -> List[str]:
|
||||
return ans
|
||||
|
||||
|
||||
def config_lines(all_options):
|
||||
def config_lines(
|
||||
all_options: Dict[str, Union[Option, Sequence[Shortcut]]],
|
||||
) -> Generator[str, None, None]:
|
||||
for opt in all_options.values():
|
||||
if isinstance(opt, Option):
|
||||
if opt.add_to_default:
|
||||
@ -310,7 +313,7 @@ def config_lines(all_options):
|
||||
|
||||
|
||||
def as_type_stub(
|
||||
all_options: Dict[str, Union[Option, List[Shortcut]]],
|
||||
all_options: Dict[str, Union[Option, Sequence[Shortcut]]],
|
||||
special_types: Optional[Dict[str, str]] = None,
|
||||
preamble_lines: Union[Tuple[str, ...], List[str], Iterable[str]] = (),
|
||||
extra_fields: Union[Tuple[Tuple[str, str], ...], List[Tuple[str, str]], Iterable[Tuple[str, str]]] = (),
|
||||
|
||||
@ -6,14 +6,15 @@ import os
|
||||
import re
|
||||
import shlex
|
||||
from typing import (
|
||||
Any, Callable, Dict, FrozenSet, Iterable, List, NamedTuple, Optional,
|
||||
Sequence, Tuple, Type, Union
|
||||
Any, Callable, Dict, FrozenSet, Generator, Iterable, Iterator, List,
|
||||
NamedTuple, Optional, Sequence, Tuple, Type, TypeVar, Union
|
||||
)
|
||||
|
||||
from ..rgb import Color, to_color as as_color
|
||||
from ..utils import log_error
|
||||
|
||||
key_pat = re.compile(r'([a-zA-Z][a-zA-Z0-9_-]*)\s+(.+)$')
|
||||
T = TypeVar('T')
|
||||
|
||||
|
||||
class BadLine(NamedTuple):
|
||||
@ -153,9 +154,9 @@ def parse_config_base(
|
||||
type_convert: Callable[[str, Any], Any],
|
||||
special_handling: Callable,
|
||||
ans: Dict[str, Any],
|
||||
check_keys=True,
|
||||
check_keys: bool = True,
|
||||
accumulate_bad_lines: Optional[List[BadLine]] = None
|
||||
):
|
||||
) -> None:
|
||||
all_keys: Optional[FrozenSet[str]] = defaults._asdict() if check_keys else None
|
||||
_parse(
|
||||
lines, type_convert, special_handling, ans, all_keys, accumulate_bad_lines
|
||||
@ -166,17 +167,17 @@ def create_options_class(all_keys: Iterable[str]) -> Type:
|
||||
keys = tuple(sorted(all_keys))
|
||||
slots = keys + ('_fields', )
|
||||
|
||||
def __init__(self, kw):
|
||||
def __init__(self: Any, kw: Dict[str, Any]) -> None:
|
||||
for k, v in kw.items():
|
||||
setattr(self, k, v)
|
||||
|
||||
def __iter__(self):
|
||||
def __iter__(self: Any) -> Iterator[str]:
|
||||
return iter(keys)
|
||||
|
||||
def __len__(self):
|
||||
def __len__(self: Any) -> int:
|
||||
return len(keys)
|
||||
|
||||
def __getitem__(self, i):
|
||||
def __getitem__(self: Any, i: Union[int, str]) -> Any:
|
||||
if isinstance(i, int):
|
||||
i = keys[i]
|
||||
try:
|
||||
@ -184,10 +185,10 @@ def create_options_class(all_keys: Iterable[str]) -> Type:
|
||||
except AttributeError:
|
||||
raise KeyError('No option named: {}'.format(i))
|
||||
|
||||
def _asdict(self):
|
||||
def _asdict(self: Any) -> Dict[str, Any]:
|
||||
return {k: getattr(self, k) for k in self._fields}
|
||||
|
||||
def _replace(self, **kw):
|
||||
def _replace(self: Any, **kw: Dict) -> Any:
|
||||
ans = self._asdict()
|
||||
ans.update(kw)
|
||||
return self.__class__(ans)
|
||||
@ -213,7 +214,7 @@ def merge_dicts(defaults: Dict, newvals: Dict) -> Dict:
|
||||
return ans
|
||||
|
||||
|
||||
def resolve_config(SYSTEM_CONF: str, defconf: str, config_files_on_cmd_line: Sequence[str]):
|
||||
def resolve_config(SYSTEM_CONF: str, defconf: str, config_files_on_cmd_line: Sequence[str]) -> Generator[str, None, None]:
|
||||
if config_files_on_cmd_line:
|
||||
if 'NONE' not in config_files_on_cmd_line:
|
||||
yield SYSTEM_CONF
|
||||
@ -225,13 +226,13 @@ def resolve_config(SYSTEM_CONF: str, defconf: str, config_files_on_cmd_line: Seq
|
||||
|
||||
|
||||
def load_config(
|
||||
Options: Type,
|
||||
Options: Type[T],
|
||||
defaults: Any,
|
||||
parse_config: Callable[[Iterable[str]], Dict[str, Any]],
|
||||
merge_configs: Callable[[Dict, Dict], Dict],
|
||||
*paths: str,
|
||||
overrides: Optional[Iterable[str]] = None
|
||||
):
|
||||
) -> T:
|
||||
ans: Dict = defaults._asdict()
|
||||
for path in paths:
|
||||
if not path:
|
||||
@ -245,22 +246,22 @@ def load_config(
|
||||
if overrides is not None:
|
||||
vals = parse_config(overrides)
|
||||
ans = merge_configs(ans, vals)
|
||||
return Options(ans)
|
||||
return Options(ans) # type: ignore
|
||||
|
||||
|
||||
def init_config(default_config_lines: Iterable[str], parse_config: Callable):
|
||||
def init_config(default_config_lines: Iterable[str], parse_config: Callable) -> Tuple[Type, Any]:
|
||||
defaults = parse_config(default_config_lines, check_keys=False)
|
||||
Options = create_options_class(defaults.keys())
|
||||
defaults = Options(defaults)
|
||||
return Options, defaults
|
||||
|
||||
|
||||
def key_func():
|
||||
def key_func() -> Tuple[Callable, Dict[str, Callable]]:
|
||||
ans: Dict[str, Callable] = {}
|
||||
|
||||
def func_with_args(*names):
|
||||
def func_with_args(*names: str) -> Callable:
|
||||
|
||||
def w(f):
|
||||
def w(f: Callable) -> Callable:
|
||||
for name in names:
|
||||
if ans.setdefault(name, f) is not f:
|
||||
raise ValueError(
|
||||
|
||||
@ -11,7 +11,7 @@ from contextlib import contextmanager, suppress
|
||||
from functools import partial
|
||||
from typing import (
|
||||
Any, Callable, Dict, Iterable, List, Optional,
|
||||
Sequence, Set, Tuple, Type, cast
|
||||
Sequence, Set, Tuple, Type
|
||||
)
|
||||
|
||||
from . import fast_data_types as defines
|
||||
@ -796,7 +796,7 @@ def load_config(*paths: str, overrides: Optional[Iterable[str]] = None, accumula
|
||||
parser = parse_config
|
||||
if accumulate_bad_lines is not None:
|
||||
parser = partial(parse_config, accumulate_bad_lines=accumulate_bad_lines)
|
||||
opts = cast(OptionsStub, _load_config(Options, defaults, parser, merge_configs, *paths, overrides=overrides))
|
||||
opts = _load_config(Options, defaults, parser, merge_configs, *paths, overrides=overrides)
|
||||
finalize_keys(opts)
|
||||
if opts.background_opacity < 1.0 and opts.macos_titlebar_color:
|
||||
log_error('Cannot use both macos_titlebar_color and background_opacity')
|
||||
|
||||
@ -6,7 +6,8 @@
|
||||
import os
|
||||
from gettext import gettext as _
|
||||
from typing import (
|
||||
Any, Dict, FrozenSet, Iterable, List, Optional, Set, Tuple, TypeVar, Union
|
||||
Any, Dict, FrozenSet, Iterable, List, Optional, Sequence, Set, Tuple,
|
||||
TypeVar, Union
|
||||
)
|
||||
|
||||
from . import fast_data_types as defines
|
||||
@ -60,7 +61,7 @@ def uniq(vals: Iterable[T]) -> List[T]:
|
||||
# Groups {{{
|
||||
|
||||
|
||||
all_options: Dict[str, Union[Option, Shortcut]] = {}
|
||||
all_options: Dict[str, Union[Option, Sequence[Shortcut]]] = {}
|
||||
|
||||
|
||||
o, k, g, all_groups = option_func(all_options, {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user