Coverage for src/lilbee/__init__.py: 100%

44 statements  

« prev     ^ index     » next       coverage.py v7.15.2, created at 2026-08-14 11:46 +0000

1"""lilbee: local knowledge base.""" 

2 

3from __future__ import annotations 

4 

5import os 

6import threading 

7 

8# Suppress HF-default tqdm bars (metadata probes, snapshot summaries) that 

9# leak cursor escapes into the TUI. Our custom tqdm_class is NOT a subclass 

10# of huggingface_hub.utils.tqdm, so huggingface_hub's `_create_progress_bar` 

11# instantiates it directly without honoring this flag. Download callbacks 

12# continue to fire. See lilbee/catalog/download_progress.py::_CallbackProgressBar. 

13os.environ.setdefault("HF_HUB_DISABLE_PROGRESS_BARS", "1") 

14 

15 

16def _install_thread_only_tqdm_lock() -> None: 

17 """Pin ``tqdm.std.tqdm._lock`` to a threading RLock. 

18 

19 Bypasses tqdm's lazy multiprocessing-lock init, which tries to 

20 fork_exec the MP resource tracker with ``sys.stderr.fileno() == -1`` 

21 under Textual and crashes with ``bad value(s) in fds_to_keep``. 

22 Matches huggingface_hub PR #4065 but applied at the base class so 

23 every tqdm instance in the process inherits the lock via MRO. 

24 """ 

25 try: 

26 from tqdm.std import tqdm as _tqdm_base 

27 except ImportError: 

28 return 

29 if getattr(_tqdm_base, "_lock", None) is None: 

30 _tqdm_base._lock = threading.RLock() 

31 

32 

33def _prestart_mp_resource_tracker() -> None: 

34 """Start the multiprocessing resource tracker before Textual swaps stderr. 

35 

36 The tracker launches lazily on the first semaphore creation, which in 

37 the TUI is a worker's ``Value(lock=True)`` abort flag, spawned after 

38 Textual has replaced ``sys.stderr`` with a stream whose ``fileno()`` 

39 returns -1. The tracker's launch passes that -1 into 

40 ``_posixsubprocess.fork_exec`` and crashes with ``bad value(s) in 

41 fds_to_keep``. Launching it here, at import time with a real stderr, 

42 caches a valid tracker fd that every later ``Process.start()`` reuses. 

43 

44 Runs in frozen builds too (Nuitka onefile): the tracker re-executes 

45 ``sys.executable`` with ``-c "from multiprocessing.resource_tracker 

46 import main;main(N)"``, which ``__main__._dispatch_frozen_child`` 

47 intercepts and execs before typer sees it. No-op on Windows, which 

48 does not use ``_posixsubprocess``. 

49 """ 

50 import sys as _sys 

51 

52 if _sys.platform == "win32": 

53 return 

54 try: 

55 from multiprocessing import resource_tracker 

56 

57 resource_tracker.ensure_running() 

58 except (OSError, RuntimeError, ValueError, ImportError): 

59 # Best-effort: if the tracker already crashed or cannot be started 

60 # in the current env, leave the state alone. The worker's own 

61 # spawn will surface a real error at call time. 

62 pass 

63 

64 

65_install_thread_only_tqdm_lock() 

66_prestart_mp_resource_tracker() 

67 

68 

69def _shrink_hf_download_chunk_size() -> None: 

70 """Shrink huggingface_hub's 10MB download chunk to 200KB. 

71 

72 The HTTP path fires the progress callback once per chunk, so the default 

73 leaves multi-second gaps. Patched rather than configured: there is no env 

74 override. 

75 """ 

76 try: 

77 from huggingface_hub import constants as _hf_constants 

78 

79 _hf_constants.DOWNLOAD_CHUNK_SIZE = 200 * 1024 

80 except ImportError: 

81 pass # huggingface_hub may be absent in stripped-down environments 

82 

83 

84_shrink_hf_download_chunk_size() 

85 

86 

87# HF and LiteLLM log filters live next to their respective implementations 

88# (catalog/hf_client.py and providers/litellm_sdk.py). They install themselves 

89# on module import; this package's __init__.py stays free of HF/LiteLLM 

90# implementation detail. 

91 

92 

93# Must follow HF environment / constants setup above. 

94from typing import TYPE_CHECKING # noqa: E402 

95 

96if TYPE_CHECKING: 

97 from lilbee.api import Lilbee 

98 

99__all__ = ["Lilbee"] 

100 

101 

102def __getattr__(name: str) -> object: 

103 """Lazy-load ``Lilbee`` and fall back to normal submodule import.""" 

104 if name == "Lilbee": 

105 from lilbee.api import Lilbee 

106 

107 return Lilbee 

108 if name.startswith("__") and name.endswith("__"): 

109 # Introspection probes (__wrapped__, __all__ fallbacks, copy/pickle 

110 # dunders) are frequent and never name a submodule; skip the import. 

111 raise AttributeError(f"module {__name__!r} has no attribute {name!r}") 

112 # PEP 562: `lilbee.<submodule>` must behave like a plain package attribute 

113 # even when the submodule has not been imported yet (dotted-path resolvers 

114 # such as monkeypatch.setattr and mock.patch rely on getattr succeeding). 

115 import importlib 

116 

117 try: 

118 return importlib.import_module(f".{name}", __name__) 

119 except ModuleNotFoundError as exc: 

120 if exc.name == f"{__name__}.{name}": 

121 raise AttributeError(f"module {__name__!r} has no attribute {name!r}") from None 

122 raise