Use a nicer decorator for functions that only need to be run once
This commit is contained in:
parent
726d736aac
commit
fe07306ff1
@ -3,16 +3,17 @@
|
||||
# License: GPL v3 Copyright: 2018, Kovid Goyal <kovid at kovidgoyal.net>
|
||||
|
||||
import warnings
|
||||
from functools import lru_cache
|
||||
from gettext import gettext as _
|
||||
from itertools import repeat, zip_longest
|
||||
from math import ceil
|
||||
from typing import Callable, Dict, Generator, Iterable, List, Optional, Tuple
|
||||
|
||||
from kitty.fast_data_types import truncate_point_for_length, wcswidth
|
||||
from kitty.cli_stub import DiffCLIOptions
|
||||
from kitty.fast_data_types import truncate_point_for_length, wcswidth
|
||||
from kitty.types import run_once
|
||||
from kitty.utils import ScreenSize
|
||||
|
||||
from ..tui.images import ImageManager, can_display_images
|
||||
from .collect import (
|
||||
Collection, Segment, data_for_path, highlights_for_path, is_image,
|
||||
lines_for_path, path_name_map, sanitize
|
||||
@ -20,14 +21,13 @@ from .collect import (
|
||||
from .config import formats
|
||||
from .diff_speedup import split_with_highlights as _split_with_highlights
|
||||
from .patch import Chunk, Hunk, Patch
|
||||
from ..tui.images import ImageManager, can_display_images
|
||||
|
||||
|
||||
class ImageSupportWarning(Warning):
|
||||
pass
|
||||
|
||||
|
||||
@lru_cache(maxsize=2)
|
||||
@run_once
|
||||
def images_supported() -> bool:
|
||||
ans = can_display_images()
|
||||
if not ans:
|
||||
|
||||
@ -10,7 +10,6 @@ import socket
|
||||
import sys
|
||||
import zlib
|
||||
from base64 import standard_b64encode
|
||||
from functools import lru_cache
|
||||
from math import ceil
|
||||
from tempfile import NamedTemporaryFile
|
||||
from typing import (
|
||||
@ -21,6 +20,7 @@ from kitty.cli import parse_args
|
||||
from kitty.cli_stub import IcatCLIOptions
|
||||
from kitty.constants import appname
|
||||
from kitty.guess_mime_type import guess_type
|
||||
from kitty.types import run_once
|
||||
from kitty.typing import GRT_f, GRT_t
|
||||
from kitty.utils import (
|
||||
TTYIO, ScreenSize, ScreenSizeGetter, fit_image, screen_size_function
|
||||
@ -142,7 +142,7 @@ def get_screen_size() -> ScreenSize:
|
||||
return screen_size()
|
||||
|
||||
|
||||
@lru_cache(maxsize=2)
|
||||
@run_once
|
||||
def options_spec() -> str:
|
||||
return OPTIONS.format(appname='{}-icat'.format(appname))
|
||||
|
||||
|
||||
@ -6,9 +6,11 @@
|
||||
import importlib
|
||||
import os
|
||||
import sys
|
||||
from functools import lru_cache, partial
|
||||
from functools import partial
|
||||
from typing import Any, Dict, FrozenSet, List
|
||||
|
||||
from kitty.types import run_once
|
||||
|
||||
aliases = {'url_hints': 'hints'}
|
||||
|
||||
|
||||
@ -57,8 +59,9 @@ def create_kitten_handler(kitten: str, orig_args: List[str]) -> Any:
|
||||
|
||||
|
||||
def set_debug(kitten: str) -> None:
|
||||
from kittens.tui.loop import debug
|
||||
import builtins
|
||||
|
||||
from kittens.tui.loop import debug
|
||||
setattr(builtins, 'debug', debug)
|
||||
|
||||
|
||||
@ -118,7 +121,7 @@ def run_kitten(kitten: str, run_name: str = '__main__') -> None:
|
||||
m['main'](sys.argv)
|
||||
|
||||
|
||||
@lru_cache(maxsize=2)
|
||||
@run_once
|
||||
def all_kitten_names() -> FrozenSet[str]:
|
||||
n = []
|
||||
import glob
|
||||
|
||||
@ -5,7 +5,6 @@
|
||||
import os
|
||||
import shlex
|
||||
import sys
|
||||
from functools import lru_cache
|
||||
from typing import (
|
||||
Any, Callable, Dict, Iterable, List, Optional, Sequence, Set, Tuple
|
||||
)
|
||||
@ -17,6 +16,7 @@ from .cli import (
|
||||
)
|
||||
from .rc.base import all_command_names, command_for_name
|
||||
from .shell import options_for_cmd
|
||||
from .types import run_once
|
||||
|
||||
'''
|
||||
To add completion for a new shell, you need to:
|
||||
@ -75,7 +75,7 @@ class Completions:
|
||||
self.delegate: Delegate = Delegate()
|
||||
|
||||
|
||||
@lru_cache(maxsize=2)
|
||||
@run_once
|
||||
def remote_control_command_names() -> Tuple[str, ...]:
|
||||
return tuple(sorted(x.replace('_', '-') for x in all_command_names()))
|
||||
|
||||
|
||||
@ -7,10 +7,10 @@ import os
|
||||
import pwd
|
||||
import sys
|
||||
from contextlib import suppress
|
||||
from functools import lru_cache
|
||||
from typing import NamedTuple, Optional, Set
|
||||
|
||||
from .options_stub import Options
|
||||
from .types import run_once
|
||||
|
||||
|
||||
class Version(NamedTuple):
|
||||
@ -27,7 +27,7 @@ is_macos: bool = 'darwin' in _plat
|
||||
base = os.path.dirname(os.path.abspath(__file__))
|
||||
|
||||
|
||||
@lru_cache(maxsize=2)
|
||||
@run_once
|
||||
def kitty_exe() -> str:
|
||||
rpath = sys._xoptions.get('bundle_exe_dir')
|
||||
if not rpath:
|
||||
@ -93,11 +93,8 @@ del _get_config_dir
|
||||
defconf = os.path.join(config_dir, 'kitty.conf')
|
||||
|
||||
|
||||
@lru_cache(maxsize=2)
|
||||
@run_once
|
||||
def cache_dir() -> str:
|
||||
override: Optional[str] = getattr(cache_dir, 'override_dir', None)
|
||||
if override:
|
||||
return override
|
||||
if 'KITTY_CACHE_DIRECTORY' in os.environ:
|
||||
candidate = os.path.abspath(os.environ['KITTY_CACHE_DIRECTORY'])
|
||||
elif is_macos:
|
||||
|
||||
@ -3,7 +3,6 @@
|
||||
# License: GPLv3 Copyright: 2019, Kovid Goyal <kovid at kovidgoyal.net>
|
||||
|
||||
|
||||
from functools import lru_cache
|
||||
from typing import Any, Dict, List, NamedTuple, Optional, Sequence
|
||||
|
||||
from .boss import Boss
|
||||
@ -13,6 +12,7 @@ from .cli_stub import LaunchCLIOptions
|
||||
from .constants import resolve_custom_file
|
||||
from .fast_data_types import patch_color_profiles, set_clipboard_string
|
||||
from .tabs import Tab
|
||||
from .types import run_once
|
||||
from .utils import find_exe, read_shell_environment, set_primary_selection
|
||||
from .window import Watchers, Window
|
||||
|
||||
@ -27,7 +27,7 @@ class LaunchSpec(NamedTuple):
|
||||
args: List[str]
|
||||
|
||||
|
||||
@lru_cache(maxsize=2)
|
||||
@run_once
|
||||
def options_spec() -> str:
|
||||
return '''
|
||||
--window-title --title
|
||||
|
||||
@ -6,7 +6,6 @@
|
||||
import os
|
||||
import posixpath
|
||||
from contextlib import suppress
|
||||
from functools import lru_cache
|
||||
from typing import (
|
||||
Any, Generator, Iterable, List, NamedTuple, Optional, Tuple, cast
|
||||
)
|
||||
@ -15,9 +14,10 @@ from urllib.parse import ParseResult, unquote, urlparse
|
||||
from .conf.utils import to_cmdline
|
||||
from .config import KeyAction, parse_key_action
|
||||
from .constants import config_dir
|
||||
from .guess_mime_type import guess_type
|
||||
from .types import run_once
|
||||
from .typing import MatchType
|
||||
from .utils import expandvars, log_error
|
||||
from .guess_mime_type import guess_type
|
||||
|
||||
|
||||
class MatchCriteria(NamedTuple):
|
||||
@ -175,7 +175,7 @@ def actions_for_url_from_list(url: str, actions: Iterable[OpenAction]) -> Genera
|
||||
return
|
||||
|
||||
|
||||
@lru_cache(maxsize=2)
|
||||
@run_once
|
||||
def load_open_actions() -> Tuple[OpenAction, ...]:
|
||||
try:
|
||||
f = open(os.path.join(config_dir, 'open-actions.conf'))
|
||||
|
||||
@ -21,9 +21,10 @@ from .rc.base import (
|
||||
RemoteCommand, all_command_names, command_for_name,
|
||||
display_subcommand_help, parse_subcommand_cli
|
||||
)
|
||||
from .types import run_once
|
||||
|
||||
|
||||
@lru_cache(maxsize=2)
|
||||
@run_once
|
||||
def match_commands() -> Tuple[str, ...]:
|
||||
all_commands = tuple(sorted(x.replace('_', '-') for x in all_command_names()))
|
||||
return tuple(sorted(all_commands + ('exit', 'help', 'quit')))
|
||||
|
||||
@ -2,7 +2,10 @@
|
||||
# vim:fileencoding=utf-8
|
||||
# License: GPLv3 Copyright: 2021, Kovid Goyal <kovid at kovidgoyal.net>
|
||||
|
||||
from typing import NamedTuple, Union
|
||||
from functools import update_wrapper
|
||||
from typing import TYPE_CHECKING, Callable, Generic, NamedTuple, TypeVar, Union
|
||||
|
||||
_T = TypeVar('_T')
|
||||
|
||||
|
||||
class ParsedShortcut(NamedTuple):
|
||||
@ -50,3 +53,36 @@ class SingleKey(NamedTuple):
|
||||
|
||||
|
||||
ConvertibleToNumbers = Union[str, bytes, int, float]
|
||||
|
||||
|
||||
if TYPE_CHECKING:
|
||||
class RunOnce(Generic[_T]):
|
||||
|
||||
def __init__(self, func: Callable[[], _T]): ...
|
||||
def __call__(self) -> _T: ...
|
||||
def set_override(self, val: _T) -> None: ...
|
||||
def clear_override(self) -> None: ...
|
||||
else:
|
||||
class RunOnce:
|
||||
|
||||
def __init__(self, f):
|
||||
self._override = RunOnce
|
||||
self._cached_result = RunOnce
|
||||
update_wrapper(self, f)
|
||||
|
||||
def __call__(self):
|
||||
if self._override is not RunOnce:
|
||||
return self._override
|
||||
if self._cached_result is RunOnce:
|
||||
self._cached_result = self.__wrapped__()
|
||||
return self._cached_result
|
||||
|
||||
def set_override(self, val):
|
||||
self._override = val
|
||||
|
||||
def clear_override(self):
|
||||
self._override = RunOnce
|
||||
|
||||
|
||||
def run_once(f: Callable[[], _T]) -> RunOnce:
|
||||
return RunOnce(f)
|
||||
|
||||
@ -23,7 +23,7 @@ from .constants import (
|
||||
)
|
||||
from .options_stub import Options
|
||||
from .rgb import Color, to_color
|
||||
from .types import ConvertibleToNumbers
|
||||
from .types import ConvertibleToNumbers, run_once
|
||||
from .typing import AddressFamily, PopenType, Socket, StartupCtx
|
||||
|
||||
BASE = os.path.dirname(os.path.abspath(__file__))
|
||||
@ -463,7 +463,7 @@ def natsort_ints(iterable: Iterable[str]) -> List[str]:
|
||||
return sorted(iterable, key=alphanum_key)
|
||||
|
||||
|
||||
@lru_cache(maxsize=2)
|
||||
@run_once
|
||||
def get_editor() -> List[str]:
|
||||
import shlex
|
||||
import shutil
|
||||
@ -512,7 +512,7 @@ def resolved_shell(opts: Optional[Options] = None) -> List[str]:
|
||||
return ans
|
||||
|
||||
|
||||
@lru_cache(maxsize=2)
|
||||
@run_once
|
||||
def system_paths_on_macos() -> List[str]:
|
||||
entries, seen = [], set()
|
||||
|
||||
|
||||
@ -180,12 +180,11 @@ def make_send_command(screen):
|
||||
class TestGraphics(BaseTest):
|
||||
|
||||
def setUp(self):
|
||||
cache_dir.override_dir = tempfile.mkdtemp()
|
||||
cache_dir.cache_clear()
|
||||
cache_dir.set_override(tempfile.mkdtemp())
|
||||
|
||||
def tearDown(self):
|
||||
os.rmdir(cache_dir.override_dir)
|
||||
cache_dir.override_dir = None
|
||||
os.rmdir(cache_dir())
|
||||
cache_dir.clear_override()
|
||||
|
||||
def test_xor_data(self):
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user