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

39 statements  

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

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

2 

3from __future__ import annotations 

4 

5import os 

6import sys 

7import threading 

8 

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

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

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

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

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

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

15 

16 

17def _disable_xet_where_it_stalls() -> None: 

18 """Fall back to the plain HTTP download path on Windows. 

19 

20 hf_xet transfers stall or deadlock on Windows (xet-core issues #446, #789, 

21 #850), while the plain path downloads at line speed. Everywhere else xet 

22 stays on: it is the fast path. huggingface_hub parses the variable once at 

23 its import, so it is set here at import, before anything imports the hub, 

24 and a variable the user exported wins. 

25 """ 

26 if sys.platform == "win32": 

27 os.environ.setdefault("HF_HUB_DISABLE_XET", "1") 

28 

29 

30_disable_xet_where_it_stalls() 

31 

32 

33def _install_thread_only_tqdm_lock() -> None: 

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

35 

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

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

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

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

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

41 """ 

42 try: 

43 from tqdm.std import tqdm as _tqdm_base 

44 except ImportError: 

45 return 

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

47 _tqdm_base._lock = threading.RLock() 

48 

49 

50_install_thread_only_tqdm_lock() 

51 

52 

53def _shrink_hf_download_chunk_size() -> None: 

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

55 

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

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

58 override. 

59 """ 

60 try: 

61 from huggingface_hub import constants as _hf_constants 

62 

63 _hf_constants.DOWNLOAD_CHUNK_SIZE = 200 * 1024 

64 except ImportError: 

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

66 

67 

68_shrink_hf_download_chunk_size() 

69 

70 

71# The HF log filter lives next to its implementation (catalog/hf_client.py). 

72# It installs itself on module import; this package's __init__.py stays free of 

73# HF implementation detail. 

74 

75 

76# Must follow HF environment / constants setup above. 

77from typing import TYPE_CHECKING # noqa: E402 

78 

79if TYPE_CHECKING: 

80 from lilbee.api import Lilbee 

81 

82__all__ = ["Lilbee"] 

83 

84 

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

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

87 if name == "Lilbee": 

88 from lilbee.api import Lilbee 

89 

90 return Lilbee 

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

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

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

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

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

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

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

98 import importlib 

99 

100 try: 

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

102 except ModuleNotFoundError as exc: 

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

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

105 raise