Update codebase to Python 3.10 using pyupgrade

This commit is contained in:
Kovid Goyal
2025-01-10 22:31:41 +05:30
parent 922d08516b
commit da1626090a
126 changed files with 1739 additions and 1764 deletions

890
kitty/options/parse.py generated

File diff suppressed because it is too large Load Diff

112
kitty/options/types.py generated
View File

@@ -476,17 +476,17 @@ option_names = (
class Options:
active_border_color: typing.Optional[kitty.fast_data_types.Color] = Color(0, 255, 0)
active_border_color: kitty.fast_data_types.Color | None = Color(0, 255, 0)
active_tab_background: Color = Color(238, 238, 238)
active_tab_font_style: typing.Tuple[bool, bool] = (True, True)
active_tab_font_style: tuple[bool, bool] = (True, True)
active_tab_foreground: Color = Color(0, 0, 0)
active_tab_title_template: typing.Optional[str] = None
active_tab_title_template: str | None = None
allow_cloning: choices_for_allow_cloning = 'ask'
allow_hyperlinks: int = 1
allow_remote_control: choices_for_allow_remote_control = 'no'
background: Color = Color(0, 0, 0)
background_blur: int = 0
background_image: typing.Optional[str] = None
background_image: str | None = None
background_image_layout: choices_for_background_image_layout = 'tiled'
background_image_linear: bool = False
background_opacity: float = 1.0
@@ -494,29 +494,29 @@ class Options:
background_tint_gaps: float = 1.0
bell_border_color: Color = Color(255, 90, 0)
bell_on_tab: str = '🔔 '
bell_path: typing.Optional[str] = None
bell_path: str | None = None
bold_font: FontSpec = FontSpec(family=None, style=None, postscript_name=None, full_name=None, system='auto', axes=(), variable_name=None, features=(), created_from_string='auto')
bold_italic_font: FontSpec = FontSpec(family=None, style=None, postscript_name=None, full_name=None, system='auto', axes=(), variable_name=None, features=(), created_from_string='auto')
box_drawing_scale: typing.Tuple[float, float, float, float] = (0.001, 1.0, 1.5, 2.0)
box_drawing_scale: tuple[float, float, float, float] = (0.001, 1.0, 1.5, 2.0)
clear_all_mouse_actions: bool = False
clear_all_shortcuts: bool = False
click_interval: float = -1.0
clipboard_control: typing.Tuple[str, ...] = ('write-clipboard', 'write-primary', 'read-clipboard-ask', 'read-primary-ask')
clipboard_control: tuple[str, ...] = ('write-clipboard', 'write-primary', 'read-clipboard-ask', 'read-primary-ask')
clipboard_max_size: float = 512.0
clone_source_strategies: typing.FrozenSet[str] = frozenset({'conda', 'env_var', 'path', 'venv'})
clone_source_strategies: frozenset[str] = frozenset({'conda', 'env_var', 'path', 'venv'})
close_on_child_death: bool = False
command_on_bell: typing.List[str] = ['none']
command_on_bell: list[str] = ['none']
confirm_os_window_close: int = -1
copy_on_select: str = ''
cursor: typing.Optional[kitty.fast_data_types.Color] = Color(204, 204, 204)
cursor: kitty.fast_data_types.Color | None = Color(204, 204, 204)
cursor_beam_thickness: float = 1.5
cursor_blink_interval: typing.Tuple[float, kitty.options.utils.EasingFunction, kitty.options.utils.EasingFunction] = (-1.0, kitty.options.utils.EasingFunction(), kitty.options.utils.EasingFunction())
cursor_blink_interval: tuple[float, kitty.options.utils.EasingFunction, kitty.options.utils.EasingFunction] = (-1.0, kitty.options.utils.EasingFunction(), kitty.options.utils.EasingFunction())
cursor_shape: int = 1
cursor_shape_unfocused: int = 4
cursor_stop_blinking_after: float = 15.0
cursor_text_color: typing.Optional[kitty.fast_data_types.Color] = Color(17, 17, 17)
cursor_text_color: kitty.fast_data_types.Color | None = Color(17, 17, 17)
cursor_trail: int = 0
cursor_trail_decay: typing.Tuple[float, float] = (0.1, 0.4)
cursor_trail_decay: tuple[float, float] = (0.1, 0.4)
cursor_trail_start_threshold: int = 2
cursor_underline_thickness: float = 2.0
default_pointer_shape: choices_for_default_pointer_shape = 'beam'
@@ -527,7 +527,7 @@ class Options:
dynamic_background_opacity: bool = False
editor: str = '.'
enable_audio_bell: bool = True
enabled_layouts: typing.List[str] = ['fat', 'grid', 'horizontal', 'splits', 'stack', 'tall', 'vertical']
enabled_layouts: list[str] = ['fat', 'grid', 'horizontal', 'splits', 'stack', 'tall', 'vertical']
file_transfer_confirmation_bypass: str = ''
focus_follows_mouse: bool = False
font_family: FontSpec = FontSpec(family=None, style=None, postscript_name=None, full_name=None, system='monospace', axes=(), variable_name=None, features=(), created_from_string='monospace')
@@ -538,11 +538,11 @@ class Options:
hide_window_decorations: int = 0
inactive_border_color: Color = Color(204, 204, 204)
inactive_tab_background: Color = Color(153, 153, 153)
inactive_tab_font_style: typing.Tuple[bool, bool] = (False, False)
inactive_tab_font_style: tuple[bool, bool] = (False, False)
inactive_tab_foreground: Color = Color(68, 68, 68)
inactive_text_alpha: float = 1.0
initial_window_height: typing.Tuple[int, str] = (400, 'px')
initial_window_width: typing.Tuple[int, str] = (640, 'px')
initial_window_height: tuple[int, str] = (400, 'px')
initial_window_width: tuple[int, str] = (640, 'px')
input_delay: int = 3
italic_font: FontSpec = FontSpec(family=None, style=None, postscript_name=None, full_name=None, system='auto', axes=(), variable_name=None, features=(), created_from_string='auto')
kitty_mod: int = 5
@@ -568,42 +568,42 @@ class Options:
mark3_foreground: Color = Color(0, 0, 0)
mouse_hide_wait: float = 0.0 if is_macos else 3.0
notify_on_cmd_finish: NotifyOnCmdFinish = NotifyOnCmdFinish(when='never', duration=5.0, action='notify', cmdline=(), clear_on=('focus', 'next'))
open_url_with: typing.List[str] = ['default']
paste_actions: typing.FrozenSet[str] = frozenset({'confirm', 'quote-urls-at-prompt'})
open_url_with: list[str] = ['default']
paste_actions: frozenset[str] = frozenset({'confirm', 'quote-urls-at-prompt'})
placement_strategy: choices_for_placement_strategy = 'center'
pointer_shape_when_dragging: choices_for_pointer_shape_when_dragging = 'beam'
pointer_shape_when_grabbed: choices_for_pointer_shape_when_grabbed = 'arrow'
remember_window_size: bool = True
repaint_delay: int = 10
resize_debounce_time: typing.Tuple[float, float] = (0.1, 0.5)
resize_debounce_time: tuple[float, float] = (0.1, 0.5)
resize_in_steps: bool = False
scrollback_fill_enlarged_window: bool = False
scrollback_indicator_opacity: float = 1.0
scrollback_lines: int = 2000
scrollback_pager: typing.List[str] = ['less', '--chop-long-lines', '--RAW-CONTROL-CHARS', '+INPUT_LINE_NUMBER']
scrollback_pager: list[str] = ['less', '--chop-long-lines', '--RAW-CONTROL-CHARS', '+INPUT_LINE_NUMBER']
scrollback_pager_history_size: int = 0
select_by_word_characters: str = '@-./_~?&=%+#'
select_by_word_characters_forward: str = ''
selection_background: typing.Optional[kitty.fast_data_types.Color] = Color(255, 250, 205)
selection_foreground: typing.Optional[kitty.fast_data_types.Color] = Color(0, 0, 0)
selection_background: kitty.fast_data_types.Color | None = Color(255, 250, 205)
selection_foreground: kitty.fast_data_types.Color | None = Color(0, 0, 0)
shell: str = '.'
shell_integration: typing.FrozenSet[str] = frozenset({'enabled'})
shell_integration: frozenset[str] = frozenset({'enabled'})
show_hyperlink_targets: bool = False
single_window_margin_width: FloatEdges = FloatEdges(left=-1.0, top=-1.0, right=-1.0, bottom=-1.0)
single_window_padding_width: FloatEdges = FloatEdges(left=-1.0, top=-1.0, right=-1.0, bottom=-1.0)
startup_session: typing.Optional[str] = None
startup_session: str | None = None
strip_trailing_spaces: choices_for_strip_trailing_spaces = 'never'
sync_to_monitor: bool = True
tab_activity_symbol: str = ''
tab_bar_align: choices_for_tab_bar_align = 'left'
tab_bar_background: typing.Optional[kitty.fast_data_types.Color] = None
tab_bar_background: kitty.fast_data_types.Color | None = None
tab_bar_edge: int = 3
tab_bar_margin_color: typing.Optional[kitty.fast_data_types.Color] = None
tab_bar_margin_color: kitty.fast_data_types.Color | None = None
tab_bar_margin_height: TabBarMarginHeight = TabBarMarginHeight(outer=0, inner=0)
tab_bar_margin_width: float = 0
tab_bar_min_tabs: int = 2
tab_bar_style: choices_for_tab_bar_style = 'fade'
tab_fade: typing.Tuple[float, ...] = (0.25, 0.5, 0.75, 1.0)
tab_fade: tuple[float, ...] = (0.25, 0.5, 0.75, 1.0)
tab_powerline_style: choices_for_tab_powerline_style = 'angled'
tab_separator: str = ''
tab_switch_strategy: choices_for_tab_switch_strategy = 'previous'
@@ -614,48 +614,48 @@ class Options:
text_composition_strategy: str = 'platform'
text_fg_override_threshold: float = 0.0
touch_scroll_multiplier: float = 1.0
transparent_background_colors: typing.Tuple[typing.Tuple[kitty.fast_data_types.Color, float], ...] = ()
transparent_background_colors: tuple[tuple[kitty.fast_data_types.Color, float], ...] = ()
undercurl_style: choices_for_undercurl_style = 'thin-sparse'
underline_exclusion: tuple[float, typing.Literal['', 'px', 'pt']] = (1.0, '')
underline_hyperlinks: choices_for_underline_hyperlinks = 'hover'
update_check_interval: float = 24.0
url_color: Color = Color(0, 135, 189)
url_excluded_characters: str = ''
url_prefixes: typing.Tuple[str, ...] = ('file', 'ftp', 'ftps', 'gemini', 'git', 'gopher', 'http', 'https', 'irc', 'ircs', 'kitty', 'mailto', 'news', 'sftp', 'ssh')
url_prefixes: tuple[str, ...] = ('file', 'ftp', 'ftps', 'gemini', 'git', 'gopher', 'http', 'https', 'irc', 'ircs', 'kitty', 'mailto', 'news', 'sftp', 'ssh')
url_style: int = 3
visual_bell_color: typing.Optional[kitty.fast_data_types.Color] = None
visual_bell_duration: typing.Tuple[float, kitty.options.utils.EasingFunction, kitty.options.utils.EasingFunction] = (0.0, kitty.options.utils.EasingFunction(), kitty.options.utils.EasingFunction())
visual_bell_color: kitty.fast_data_types.Color | None = None
visual_bell_duration: tuple[float, kitty.options.utils.EasingFunction, kitty.options.utils.EasingFunction] = (0.0, kitty.options.utils.EasingFunction(), kitty.options.utils.EasingFunction())
visual_window_select_characters: str = '1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ'
wayland_enable_ime: bool = True
wayland_titlebar_color: int = 0
wheel_scroll_min_lines: int = 1
wheel_scroll_multiplier: float = 5.0
window_alert_on_bell: bool = True
window_border_width: typing.Tuple[float, str] = (0.5, 'pt')
window_border_width: tuple[float, str] = (0.5, 'pt')
window_logo_alpha: float = 0.5
window_logo_path: typing.Optional[str] = None
window_logo_path: str | None = None
window_logo_position: choices_for_window_logo_position = 'bottom-right'
window_logo_scale: typing.Tuple[float, float] = (0, -1.0)
window_logo_scale: tuple[float, float] = (0, -1.0)
window_margin_width: FloatEdges = FloatEdges(left=0, top=0, right=0, bottom=0)
window_padding_width: FloatEdges = FloatEdges(left=0, top=0, right=0, bottom=0)
window_resize_step_cells: int = 2
window_resize_step_lines: int = 2
action_alias: typing.Dict[str, str] = {}
env: typing.Dict[str, str] = {}
exe_search_path: typing.Dict[str, str] = {}
filter_notification: typing.Dict[str, str] = {}
font_features: typing.Dict[str, typing.Tuple[kitty.fast_data_types.ParsedFontFeature, ...]] = {}
kitten_alias: typing.Dict[str, str] = {}
menu_map: typing.Dict[typing.Tuple[str, ...], str] = {}
modify_font: typing.Dict[str, kitty.fonts.FontModification] = {}
narrow_symbols: typing.Dict[typing.Tuple[int, int], int] = {}
remote_control_password: typing.Dict[str, typing.Sequence[str]] = {}
symbol_map: typing.Dict[typing.Tuple[int, int], str] = {}
watcher: typing.Dict[str, str] = {}
map: typing.List[kitty.options.utils.KeyDefinition] = []
action_alias: dict[str, str] = {}
env: dict[str, str] = {}
exe_search_path: dict[str, str] = {}
filter_notification: dict[str, str] = {}
font_features: dict[str, tuple[kitty.fast_data_types.ParsedFontFeature, ...]] = {}
kitten_alias: dict[str, str] = {}
menu_map: dict[tuple[str, ...], str] = {}
modify_font: dict[str, kitty.fonts.FontModification] = {}
narrow_symbols: dict[tuple[int, int], int] = {}
remote_control_password: dict[str, typing.Sequence[str]] = {}
symbol_map: dict[tuple[int, int], str] = {}
watcher: dict[str, str] = {}
map: list[kitty.options.utils.KeyDefinition] = []
keyboard_modes: KeyboardModeMap = {}
alias_map: AliasMap = AliasMap()
mouse_map: typing.List[kitty.options.utils.MouseMapping] = []
mouse_map: list[kitty.options.utils.MouseMapping] = []
mousemap: MouseMap = {}
color_table: "array[int]" = array("L", (
0x000000, 0xcc0403, 0x19cb00, 0xcecb00, 0x0d73cc, 0xcb1ed1, 0x0dcdcd, 0xdddddd,
@@ -691,11 +691,11 @@ class Options:
0x585858, 0x626262, 0x6c6c6c, 0x767676, 0x808080, 0x8a8a8a, 0x949494, 0x9e9e9e,
0xa8a8a8, 0xb2b2b2, 0xbcbcbc, 0xc6c6c6, 0xd0d0d0, 0xdadada, 0xe4e4e4, 0xeeeeee,
))
config_paths: typing.Tuple[str, ...] = ()
all_config_paths: typing.Tuple[str, ...] = ()
config_overrides: typing.Tuple[str, ...] = ()
config_paths: tuple[str, ...] = ()
all_config_paths: tuple[str, ...] = ()
config_overrides: tuple[str, ...] = ()
def __init__(self, options_dict: typing.Optional[typing.Dict[str, typing.Any]] = None) -> None:
def __init__(self, options_dict: dict[str, typing.Any] | None = None) -> None:
self.color_table = array(self.color_table.typecode, self.color_table)
if options_dict is not None:
null = object()
@@ -705,7 +705,7 @@ class Options:
setattr(self, key, val)
@property
def _fields(self) -> typing.Tuple[str, ...]:
def _fields(self) -> tuple[str, ...]:
return option_names
def __iter__(self) -> typing.Iterator[str]:
@@ -722,7 +722,7 @@ class Options:
ans = ans[:]
return ans
def _asdict(self) -> typing.Dict[str, typing.Any]:
def _asdict(self) -> dict[str, typing.Any]:
return {k: self._copy_of_val(k) for k in self}
def _replace(self, **kw: typing.Any) -> "Options":
@@ -733,7 +733,7 @@ class Options:
setattr(ans, name, val)
return ans
def __getitem__(self, key: typing.Union[int, str]) -> typing.Any:
def __getitem__(self, key: int | str) -> typing.Any:
k = option_names[key] if isinstance(key, int) else key
try:
return getattr(self, k)

View File

@@ -6,26 +6,16 @@ import enum
import re
import sys
from collections import defaultdict
from collections.abc import Callable, Container, Iterable, Iterator, Sequence
from contextlib import suppress
from dataclasses import dataclass, fields
from functools import lru_cache
from typing import (
Any,
Callable,
Container,
Dict,
FrozenSet,
Generic,
Iterable,
Iterator,
List,
Literal,
NamedTuple,
Optional,
Sequence,
Tuple,
TypeVar,
Union,
cast,
get_args,
)
@@ -54,20 +44,20 @@ from kitty.rgb import color_as_int
from kitty.types import FloatEdges, MouseEvent
from kitty.utils import expandvars, log_error, resolve_abs_or_config_path, shlex_split
KeyMap = Dict[SingleKey, List['KeyDefinition']]
MouseMap = Dict[MouseEvent, str]
KeySequence = Tuple[SingleKey, ...]
KeyMap = dict[SingleKey, list['KeyDefinition']]
MouseMap = dict[MouseEvent, str]
KeySequence = tuple[SingleKey, ...]
MINIMUM_FONT_SIZE = 4
default_tab_separator = ''
mod_map = {'': 'CONTROL', 'CTRL': 'CONTROL', '': 'SHIFT', '': 'ALT', 'OPTION': 'ALT', 'OPT': 'ALT',
'': 'SUPER', 'COMMAND': 'SUPER', 'CMD': 'SUPER', 'KITTY_MOD': 'KITTY'}
character_key_name_aliases_with_ascii_lowercase: Dict[str, str] = character_key_name_aliases.copy()
character_key_name_aliases_with_ascii_lowercase: dict[str, str] = character_key_name_aliases.copy()
for x in 'ABCDEFGHIJKLMNOPQRSTUVWXYZ':
character_key_name_aliases_with_ascii_lowercase[x] = x.lower()
sequence_sep = '>'
mouse_button_map = {'left': 'b1', 'middle': 'b3', 'right': 'b2'}
mouse_trigger_count_map = {'doubleclick': -3, 'click': -2, 'release': -1, 'press': 1, 'doublepress': 2, 'triplepress': 3}
FuncArgsType = Tuple[str, Sequence[Any]]
FuncArgsType = tuple[str, Sequence[Any]]
func_with_args = KeyFuncWrapper[FuncArgsType]()
DELETE_ENV_VAR = '_delete_this_env_var_'
@@ -200,13 +190,13 @@ def signal_child_parse(func: str, rest: str) -> FuncArgsType:
@func_with_args('change_font_size')
def parse_change_font_size(func: str, rest: str) -> Tuple[str, Tuple[bool, Optional[str], float]]:
def parse_change_font_size(func: str, rest: str) -> tuple[str, tuple[bool, str | None, float]]:
vals = rest.strip().split(maxsplit=1)
if len(vals) != 2:
log_error(f'Invalid change_font_size specification: {rest}, treating it as default')
return func, (True, None, 0)
c_all = vals[0].lower() == 'all'
sign: Optional[str] = None
sign: str | None = None
amt = vals[1]
if amt[0] in '+-':
sign = amt[0]
@@ -284,7 +274,7 @@ def resize_window(func: str, rest: str) -> FuncArgsType:
def move_window(func: str, rest: str) -> FuncArgsType:
rest = rest.lower()
rest = {'up': 'top', 'down': 'bottom'}.get(rest, rest)
prest: Union[int, str] = rest
prest: int | str = rest
try:
prest = int(prest)
except Exception:
@@ -370,7 +360,7 @@ def layout_action(func: str, rest: str) -> FuncArgsType:
return func, [parts[0], tuple(parts[1:])]
def parse_marker_spec(ftype: str, parts: Sequence[str]) -> Tuple[str, Union[str, Tuple[Tuple[int, str], ...]], int]:
def parse_marker_spec(ftype: str, parts: Sequence[str]) -> tuple[str, str | tuple[tuple[int, str], ...], int]:
flags = re.UNICODE
if ftype in ('text', 'itext', 'regex', 'iregex'):
if ftype.startswith('i'):
@@ -388,7 +378,7 @@ def parse_marker_spec(ftype: str, parts: Sequence[str]) -> Tuple[str, Union[str,
sspec = re.escape(sspec)
ans.append((color, sspec))
ftype = 'regex'
spec: Union[str, Tuple[Tuple[int, str], ...]] = tuple(ans)
spec: str | tuple[tuple[int, str], ...] = tuple(ans)
elif ftype == 'function':
spec = ' '.join(parts)
else:
@@ -446,7 +436,7 @@ def load_config_file(func: str, rest: str) -> FuncArgsType:
# }}}
def parse_mods(parts: Iterable[str], sc: str) -> Optional[int]:
def parse_mods(parts: Iterable[str], sc: str) -> int | None:
def map_mod(m: str) -> str:
return mod_map.get(m, m)
@@ -492,7 +482,7 @@ def parse_shortcut(sc: str) -> SingleKey:
except Exception:
uq = q.upper()
uq = functional_key_name_aliases.get(uq, uq)
x: Optional[int] = getattr(defines, f'GLFW_FKEY_{uq}', None)
x: int | None = getattr(defines, f'GLFW_FKEY_{uq}', None)
if x is None:
lf = get_key_name_lookup()
key = lf(q, False) or 0
@@ -512,14 +502,14 @@ def disable_ligatures(x: str) -> int:
return cmap.get(x.lower(), 0)
def box_drawing_scale(x: str) -> Tuple[float, float, float, float]:
def box_drawing_scale(x: str) -> tuple[float, float, float, float]:
ans = tuple(float(q.strip()) for q in x.split(','))
if len(ans) != 4:
raise ValueError('Invalid box_drawing scale, must have four entries')
return ans[0], ans[1], ans[2], ans[3]
def cursor_text_color(x: str) -> Optional[Color]:
def cursor_text_color(x: str) -> Color | None:
if x.lower() == 'background':
return None
return to_color(x)
@@ -560,7 +550,7 @@ def to_cursor_unfocused_shape(x: str) -> int:
)
)
def cursor_trail_decay(x: str) -> Tuple[float, float]:
def cursor_trail_decay(x: str) -> tuple[float, float]:
fast, slow = map(positive_float, x.split())
slow = max(slow, fast)
return fast, slow
@@ -586,7 +576,7 @@ def url_style(x: str) -> int:
return url_style_map.get(x, url_style_map['curly'])
def url_prefixes(x: str) -> Tuple[str, ...]:
def url_prefixes(x: str) -> tuple[str, ...]:
return tuple(a.lower() for a in x.replace(',', ' ').split())
@@ -600,13 +590,13 @@ def copy_on_select(raw: str) -> str:
return raw
def window_size(val: str) -> Tuple[int, str]:
def window_size(val: str) -> tuple[int, str]:
val = val.lower()
unit = 'cells' if val.endswith('c') else 'px'
return positive_int(val.rstrip('c')), unit
def parse_layout_names(parts: Iterable[str]) -> List[str]:
def parse_layout_names(parts: Iterable[str]) -> list[str]:
from kitty.layout.interface import all_layouts
ans = []
for p in parts:
@@ -621,11 +611,11 @@ def parse_layout_names(parts: Iterable[str]) -> List[str]:
return uniq(ans)
def to_layout_names(raw: str) -> List[str]:
def to_layout_names(raw: str) -> list[str]:
return parse_layout_names(x.strip() for x in raw.split(','))
def window_border_width(x: Union[str, int, float]) -> Tuple[float, str]:
def window_border_width(x: str | int | float) -> tuple[float, str]:
unit = 'pt'
if isinstance(x, str):
trailer = x[-2:]
@@ -675,14 +665,14 @@ def resize_draw_strategy(x: str) -> int:
return cmap.get(x.lower(), 0)
def window_logo_scale(x: str) -> Tuple[float, float]:
def window_logo_scale(x: str) -> tuple[float, float]:
parts = x.split(maxsplit=1)
if len(parts) == 1:
return positive_float(parts[0]), -1.0
return positive_float(parts[0]), positive_float(parts[1])
def resize_debounce_time(x: str) -> Tuple[float, float]:
def resize_debounce_time(x: str) -> tuple[float, float]:
parts = x.split(maxsplit=1)
if len(parts) == 1:
return positive_float(parts[0]), 0.5
@@ -717,7 +707,7 @@ def tab_bar_edge(x: str) -> int:
return {'top': 1, 'bottom': 3}.get(x.lower(), 3)
def tab_font_style(x: str) -> Tuple[bool, bool]:
def tab_font_style(x: str) -> tuple[bool, bool]:
return {
'bold-italic': (True, True),
'bold': (True, False),
@@ -729,7 +719,7 @@ def tab_bar_min_tabs(x: str) -> int:
return max(1, positive_int(x))
def tab_fade(x: str) -> Tuple[float, ...]:
def tab_fade(x: str) -> tuple[float, ...]:
return tuple(map(unit_float, x.split()))
@@ -757,7 +747,7 @@ def tab_title_template(x: str) -> str:
return x
def active_tab_title_template(x: str) -> Optional[str]:
def active_tab_title_template(x: str) -> str | None:
x = tab_title_template(x)
return None if x == 'none' else x
@@ -771,7 +761,7 @@ class NotifyOnCmdFinish(NamedTuple):
when: str = 'never'
duration: float = 5.0
action: str = 'notify'
cmdline: Tuple[str, ...] = ()
cmdline: tuple[str, ...] = ()
clear_on: tuple[ClearOn, ...] = default_clear_on
@@ -784,7 +774,7 @@ def notify_on_cmd_finish(x: str) -> NotifyOnCmdFinish:
if len(parts) > 1:
duration = float(parts[1])
action = 'notify'
cmdline: Tuple[str, ...] = ()
cmdline: tuple[str, ...] = ()
clear_on = default_clear_on
if len(parts) > 2:
if parts[2] not in ('notify', 'bell', 'command'):
@@ -807,17 +797,17 @@ def notify_on_cmd_finish(x: str) -> NotifyOnCmdFinish:
return NotifyOnCmdFinish(when, duration, action, cmdline, clear_on)
def config_or_absolute_path(x: str, env: Optional[Dict[str, str]] = None) -> Optional[str]:
def config_or_absolute_path(x: str, env: dict[str, str] | None = None) -> str | None:
if not x or x.lower() == 'none':
return None
return resolve_abs_or_config_path(x, env)
def filter_notification(val: str, current_val: Dict[str, str]) -> Iterable[Tuple[str, str]]:
def filter_notification(val: str, current_val: dict[str, str]) -> Iterable[tuple[str, str]]:
yield val, ''
def remote_control_password(val: str, current_val: Dict[str, str]) -> Iterable[Tuple[str, Sequence[str]]]:
def remote_control_password(val: str, current_val: dict[str, str]) -> Iterable[tuple[str, Sequence[str]]]:
val = val.strip()
if val:
parts = to_cmdline(val, expand=False)
@@ -831,7 +821,7 @@ def remote_control_password(val: str, current_val: Dict[str, str]) -> Iterable[T
yield parts[0], tuple(parts[1:])
def clipboard_control(x: str) -> Tuple[str, ...]:
def clipboard_control(x: str) -> tuple[str, ...]:
return tuple(x.lower().split())
@@ -893,25 +883,25 @@ def tab_bar_margin_height(x: str) -> TabBarMarginHeight:
return TabBarMarginHeight(next(ans), next(ans))
def clone_source_strategies(x: str) -> FrozenSet[str]:
def clone_source_strategies(x: str) -> frozenset[str]:
return frozenset({'venv', 'conda', 'path', 'env_var'} & set(x.lower().split(',')))
def clear_all_mouse_actions(val: str, dict_with_parse_results: Optional[Dict[str, Any]] = None) -> bool:
def clear_all_mouse_actions(val: str, dict_with_parse_results: dict[str, Any] | None = None) -> bool:
ans = to_bool(val)
if ans and dict_with_parse_results is not None:
dict_with_parse_results['mouse_map'] = [None]
return ans
def clear_all_shortcuts(val: str, dict_with_parse_results: Optional[Dict[str, Any]] = None) -> bool:
def clear_all_shortcuts(val: str, dict_with_parse_results: dict[str, Any] | None = None) -> bool:
ans = to_bool(val)
if ans and dict_with_parse_results is not None:
dict_with_parse_results['map'] = [None]
return ans
def font_features(val: str) -> Iterable[Tuple[str, Tuple[defines.ParsedFontFeature, ...]]]:
def font_features(val: str) -> Iterable[tuple[str, tuple[defines.ParsedFontFeature, ...]]]:
if val == 'none':
return
parts = val.split()
@@ -928,13 +918,13 @@ def font_features(val: str) -> Iterable[Tuple[str, Tuple[defines.ParsedFontFeatu
yield parts[0], tuple(features)
def modify_font(val: str) -> Iterable[Tuple[str, FontModification]]:
def modify_font(val: str) -> Iterable[tuple[str, FontModification]]:
parts = val.split()
pos, plen = 0, len(parts)
if plen < 2:
log_error(f"Ignoring invalid modify_font: {val}")
return
mtype: Optional[ModificationType] = getattr(ModificationType, parts[pos], None)
mtype: ModificationType | None = getattr(ModificationType, parts[pos], None)
if mtype is None:
log_error(f"Ignoring invalid modify_font with unknown modification type: {parts[pos]}")
return
@@ -966,7 +956,7 @@ def modify_font(val: str) -> Iterable[Tuple[str, FontModification]]:
yield key, FontModification(mtype, ModificationValue(mvalue, munit), font_name)
def env(val: str, current_val: Dict[str, str]) -> Iterable[Tuple[str, str]]:
def env(val: str, current_val: dict[str, str]) -> Iterable[tuple[str, str]]:
val = val.strip()
if val:
if '=' in val:
@@ -980,13 +970,13 @@ def env(val: str, current_val: Dict[str, str]) -> Iterable[Tuple[str, str]]:
yield val, DELETE_ENV_VAR
def store_multiple(val: str, current_val: Container[str]) -> Iterable[Tuple[str, str]]:
def store_multiple(val: str, current_val: Container[str]) -> Iterable[tuple[str, str]]:
val = val.strip()
if val not in current_val:
yield val, val
def menu_map(val: str, current_val: Container[str]) -> Iterable[Tuple[Tuple[str, ...], str]]:
def menu_map(val: str, current_val: Container[str]) -> Iterable[tuple[tuple[str, ...], str]]:
parts = val.split(maxsplit=1)
if len(parts) != 2:
raise ValueError(f'Ignoring invalid menu action: {val}')
@@ -1009,7 +999,7 @@ def menu_map(val: str, current_val: Container[str]) -> Iterable[Tuple[Tuple[str,
allowed_shell_integration_values = frozenset({'enabled', 'disabled', 'no-rc', 'no-cursor', 'no-title', 'no-prompt-mark', 'no-complete', 'no-cwd', 'no-sudo'})
def shell_integration(x: str) -> FrozenSet[str]:
def shell_integration(x: str) -> frozenset[str]:
q = frozenset(x.lower().split())
if not q.issubset(allowed_shell_integration_values):
log_error(f'Invalid shell integration options: {q - allowed_shell_integration_values}, ignoring')
@@ -1031,7 +1021,7 @@ def underline_exclusion(x: str) -> tuple[float, Literal['', 'px', 'pt']]:
return val, unit
def paste_actions(x: str) -> FrozenSet[str]:
def paste_actions(x: str) -> frozenset[str]:
s = frozenset({'quote-urls-at-prompt', 'confirm', 'filter', 'confirm-if-large', 'replace-dangerous-control-codes', 'replace-newline', 'no-op'})
q = frozenset(x.lower().split(','))
if not q.issubset(s):
@@ -1039,7 +1029,7 @@ def paste_actions(x: str) -> FrozenSet[str]:
return q
def action_alias(val: str) -> Iterable[Tuple[str, str]]:
def action_alias(val: str) -> Iterable[tuple[str, str]]:
parts = val.split(maxsplit=1)
if len(parts) > 1:
alias_name, rest = parts
@@ -1049,7 +1039,7 @@ def action_alias(val: str) -> Iterable[Tuple[str, str]]:
kitten_alias = action_alias
def symbol_map_parser(val: str, min_size: int = 2) -> Iterable[Tuple[Tuple[int, int], str]]:
def symbol_map_parser(val: str, min_size: int = 2) -> Iterable[tuple[tuple[int, int], str]]:
parts = val.split()
if len(parts) < min_size:
@@ -1070,11 +1060,11 @@ def symbol_map_parser(val: str, min_size: int = 2) -> Iterable[Tuple[Tuple[int,
yield (a, b), family
def symbol_map(val: str) -> Iterable[Tuple[Tuple[int, int], str]]:
def symbol_map(val: str) -> Iterable[tuple[tuple[int, int], str]]:
yield from symbol_map_parser(val)
def narrow_symbols(val: str) -> Iterable[Tuple[Tuple[int, int], int]]:
def narrow_symbols(val: str) -> Iterable[tuple[tuple[int, int], int]]:
for x, y in symbol_map_parser(val, min_size=1):
yield x, int(y or 1)
@@ -1101,7 +1091,7 @@ class ActionAlias(NamedTuple):
class AliasMap:
def __init__(self) -> None:
self.aliases: Dict[str, List[ActionAlias]] = {}
self.aliases: dict[str, list[ActionAlias]] = {}
def append(self, name: str, aa: ActionAlias) -> None:
self.aliases.setdefault(name, []).append(aa)
@@ -1110,11 +1100,11 @@ class AliasMap:
self.aliases.update(aa.aliases)
@lru_cache(maxsize=256)
def resolve_aliases(self, definition: str, map_type: MapType = MapType.MAP) -> Tuple[KeyAction, ...]:
def resolve_aliases(self, definition: str, map_type: MapType = MapType.MAP) -> tuple[KeyAction, ...]:
return tuple(resolve_aliases_and_parse_actions(definition, self.aliases, map_type))
def build_action_aliases(raw: Dict[str, str], first_arg_replacement: str = '') -> AliasMap:
def build_action_aliases(raw: dict[str, str], first_arg_replacement: str = '') -> AliasMap:
ans = AliasMap()
if first_arg_replacement:
for alias_name, rest in raw.items():
@@ -1126,7 +1116,7 @@ def build_action_aliases(raw: Dict[str, str], first_arg_replacement: str = '') -
def resolve_aliases_and_parse_actions(
defn: str, aliases: Dict[str, List[ActionAlias]], map_type: MapType
defn: str, aliases: dict[str, list[ActionAlias]], map_type: MapType
) -> Iterator[KeyAction]:
parts = defn.split(maxsplit=1)
if len(parts) == 1:
@@ -1223,13 +1213,13 @@ T = TypeVar('T')
class LiteralField(Generic[T]):
def __init__(self, vals: Tuple[T, ...]):
def __init__(self, vals: tuple[T, ...]):
self._vals = vals
def __set_name__(self, owner: object, name: str) -> None:
self._name = "_" + name
def __get__(self, obj: object, type: Optional[type] = None) -> T:
def __get__(self, obj: object, type: type | None = None) -> T:
if obj is None:
return self._vals[0]
return getattr(obj, self._name, self._vals[0])
@@ -1261,7 +1251,7 @@ class KeyDefinition(BaseDefinition):
def __init__(
self, is_sequence: bool = False, trigger: SingleKey = SingleKey(),
rest: Tuple[SingleKey, ...] = (), definition: str = '',
rest: tuple[SingleKey, ...] = (), definition: str = '',
options: KeyMapOptions = default_key_map_options
):
super().__init__(definition)
@@ -1275,11 +1265,11 @@ class KeyDefinition(BaseDefinition):
return not self.options.when_focus_on and not self.options.mode and not self.options.new_mode and not self.is_sequence
@property
def full_key_sequence_to_trigger(self) -> Tuple[SingleKey, ...]:
def full_key_sequence_to_trigger(self) -> tuple[SingleKey, ...]:
return (self.trigger,) + self.rest
@property
def unique_identity_within_keymap(self) -> Tuple[Tuple[SingleKey, ...], str]:
def unique_identity_within_keymap(self) -> tuple[tuple[SingleKey, ...], str]:
return self.full_key_sequence_to_trigger, self.options.when_focus_on
def __repr__(self) -> str:
@@ -1309,17 +1299,17 @@ class KeyboardMode:
on_unknown: OnUnknown = get_args(OnUnknown)[0]
on_action : OnAction = get_args(OnAction)[0]
sequence_keys: Optional[List[defines.KeyEvent]] = None
sequence_keys: list[defines.KeyEvent] | None = None
def __init__(self, name: str = '') -> None:
self.name = name
self.keymap: KeyMap = defaultdict(list)
KeyboardModeMap = Dict[str, KeyboardMode]
KeyboardModeMap = dict[str, KeyboardMode]
def parse_options_for_map(val: str) -> Tuple[KeyMapOptions, str]:
def parse_options_for_map(val: str) -> tuple[KeyMapOptions, str]:
expecting_arg = ''
ans = KeyMapOptions()
s = Shlex(val)
@@ -1363,8 +1353,8 @@ def parse_map(val: str) -> Iterable[KeyDefinition]:
return
is_sequence = sequence_sep in sc
if is_sequence:
trigger: Optional[SingleKey] = None
restl: List[SingleKey] = []
trigger: SingleKey | None = None
restl: list[SingleKey] = []
for part in sc.split(sequence_sep):
try:
mods, is_native, key = parse_shortcut(part)
@@ -1447,10 +1437,10 @@ class EasingFunction(NamedTuple):
num_steps: int = 0
jump_type: JumpTypes = 'end'
linear_x: Tuple[float, ...] = ()
linear_y: Tuple[float, ...] = ()
linear_x: tuple[float, ...] = ()
linear_y: tuple[float, ...] = ()
cubic_bezier_points: Tuple[float, ...] = ()
cubic_bezier_points: tuple[float, ...] = ()
def __repr__(self) -> str:
fields = ', '.join(f'{f}={getattr(self, f)!r}' for f in self._fields if getattr(self, f) != self._field_defaults[f])
@@ -1472,8 +1462,8 @@ class EasingFunction(NamedTuple):
parts = params.split(',')
if len(parts) < 2:
raise ValueError('Must specify at least two points for the linear easing function')
xaxis: List[float] = []
yaxis: List[float] = []
xaxis: list[float] = []
yaxis: list[float] = []
def balance(end: float) -> None:
extra = len(yaxis) - len(xaxis)
@@ -1490,7 +1480,7 @@ class EasingFunction(NamedTuple):
for i in range(extra):
xaxis.append(i * delta)
def add_point(y: float, x: Optional[float] = None) -> None:
def add_point(y: float, x: float | None = None) -> None:
if x is None:
yaxis.append(y)
else:
@@ -1521,7 +1511,7 @@ class EasingFunction(NamedTuple):
if len(parts) == 2:
n = int(parts[0])
jt = parts[1]
mapping: Dict[str, JumpTypes] = {
mapping: dict[str, JumpTypes] = {
'jump-start': 'start', 'start': 'start', 'end': 'end', 'jump-end': 'end', 'jump-none': 'none', 'jump-both': 'both'
}
try:
@@ -1537,7 +1527,7 @@ class EasingFunction(NamedTuple):
return cls(type='steps', jump_type=jump_type, num_steps=n)
def parse_animation(spec: str, interval: float = -1.) -> Tuple[float, EasingFunction, EasingFunction]:
def parse_animation(spec: str, interval: float = -1.) -> tuple[float, EasingFunction, EasingFunction]:
with suppress(Exception):
interval = float(spec)
return interval, EasingFunction(), EasingFunction()
@@ -1583,15 +1573,15 @@ def parse_animation(spec: str, interval: float = -1.) -> Tuple[float, EasingFunc
return interval, m[0], m[1]
def cursor_blink_interval(spec: str) -> Tuple[float, EasingFunction, EasingFunction]:
def cursor_blink_interval(spec: str) -> tuple[float, EasingFunction, EasingFunction]:
return parse_animation(spec)
def visual_bell_duration(spec: str) -> Tuple[float, EasingFunction, EasingFunction]:
def visual_bell_duration(spec: str) -> tuple[float, EasingFunction, EasingFunction]:
return parse_animation(spec, interval=0.)
def transparent_background_colors(spec: str) -> Tuple[Tuple[Color, float], ...]:
def transparent_background_colors(spec: str) -> tuple[tuple[Color, float], ...]:
if not spec:
return ()
ans: list[tuple[Color, float]] = []
@@ -1608,7 +1598,7 @@ def transparent_background_colors(spec: str) -> Tuple[Tuple[Color, float], ...]:
return tuple(ans[:7])
def deprecated_hide_window_decorations_aliases(key: str, val: str, ans: Dict[str, Any]) -> None:
def deprecated_hide_window_decorations_aliases(key: str, val: str, ans: dict[str, Any]) -> None:
if not hasattr(deprecated_hide_window_decorations_aliases, key):
setattr(deprecated_hide_window_decorations_aliases, key, True)
log_error(f'The option {key} is deprecated. Use hide_window_decorations instead.')
@@ -1617,7 +1607,7 @@ def deprecated_hide_window_decorations_aliases(key: str, val: str, ans: Dict[str
ans['hide_window_decorations'] = True
def deprecated_macos_show_window_title_in_menubar_alias(key: str, val: str, ans: Dict[str, Any]) -> None:
def deprecated_macos_show_window_title_in_menubar_alias(key: str, val: str, ans: dict[str, Any]) -> None:
if not hasattr(deprecated_macos_show_window_title_in_menubar_alias, key):
setattr(deprecated_macos_show_window_title_in_menubar_alias, 'key', True)
log_error(f'The option {key} is deprecated. Use macos_show_window_title_in menubar instead.')
@@ -1635,7 +1625,7 @@ def deprecated_macos_show_window_title_in_menubar_alias(key: str, val: str, ans:
ans['macos_show_window_title_in'] = macos_show_window_title_in
def deprecated_send_text(key: str, val: str, ans: Dict[str, Any]) -> None:
def deprecated_send_text(key: str, val: str, ans: dict[str, Any]) -> None:
parts = val.split(' ')
def abort(msg: str) -> None:
@@ -1650,7 +1640,7 @@ def deprecated_send_text(key: str, val: str, ans: Dict[str, Any]) -> None:
ans['map'].append(k)
def deprecated_adjust_line_height(key: str, x: str, opts_dict: Dict[str, Any]) -> None:
def deprecated_adjust_line_height(key: str, x: str, opts_dict: dict[str, Any]) -> None:
fm = {'adjust_line_height': 'cell_height', 'adjust_baseline': 'baseline', 'adjust_column_width': 'cell_width'}[key]
mtype = getattr(ModificationType, fm)
if x.endswith('%'):