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