A lazy import package for both modules and items within modules.
Project description
Lazy Bear
Lazy Bear is a lightweight toolkit for deferring Python imports until the first time you actually need them. Keep startup fast, trim optional dependencies, and expose a clean API without fighting import order.
Highlights
- Drop-in
lazy("package.module")helper that mirrors a regular module object once touched. LazyLoader.to()andLazyLoader.to_many()for lazily binding one or more attributes without importing the whole module up front.LazyAttr.valuefor grabbing the underlying attribute (dicts, constants, classes) without changing call semantics.- Ideally the attribute would just be extracted but there are some issues when the item is defined within a local scope.
- Thread-safe module caching that updates
sys.modulesand the caller's globals exactly once. - Debug-friendly repr and
dir()support so interactive sessions stay intuitive even before loading. - Batteries-included CLI with version info, environment diagnostics, and release bump helpers.
Installation
Requires Python 3.13 or newer.
pip install lazy-bear
With uv:
uv tool install lazy-bear
Quick Start
from lazy_bear import lazy
json = lazy("json") # nothing imported yet
payload = {"hello": "lazy bear"}
print(json.dumps(payload, sort_keys=True))
# Module is imported the first time .dumps is accessed.
Under the hood lazy() returns a LazyLoader (a types.ModuleType subclass). Once you touch an attribute it:
- Imports the target module.
- Registers it in both
sys.modulesand the globals of the caller. - Proxies the module so future access is indistinguishable from a normal import.
Lazily Accessing Attributes
Sometimes you only need a specific callable or attribute, not the whole module namespace:
from lazy_bear import LazyAttr, lazy
console = lazy("rich.console")
Console: LazyAttr = console.to("Console")
if __name__ == "__main__":
rich_console = Console(width=100) # `rich.console` is imported here
rich_console.print("[bold green]Hello from Lazy Bear![/]")
Need multiple attributes or callables? Use to_many:
math = lazy("math")
sqrt_attr, pow_attr = math.to_many("sqrt", "pow")
print(sqrt_attr(25)) # LazyAttr stays callable
pow_func = pow_attr.value # or pow_attr.unwrap()
print(pow_func(2, 3))
LazyAttr proxies most dunder methods (__call__, __iter__, __getitem__, etc.), so lazily loaded attributes behave just like the originals.
When you need the underlying object—say a dictionary of settings—forgo calling and reach for .value (or its alias .unwrap()):
env = lazy("os").to("environ").value # returns the real os._Environ mapping
letters = lazy("string").to("ascii_letters").unwrap() # works for constants too
class Override
There is a class override in the LazyAttr class in order to get things like isinstance() support to work as expected. It isn't
100% ideal but allows the wrapper to act as the wrapped object during the moments before the wrapper is destroyed.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distributions
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file lazy_bear-0.0.12-py3-none-any.whl.
File metadata
- Download URL: lazy_bear-0.0.12-py3-none-any.whl
- Upload date:
- Size: 17.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.9.28 {"installer":{"name":"uv","version":"0.9.28","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
86dd877eda9ae0e1823b761d74ac7c58354463234be2e689f38e2d2763c9603d
|
|
| MD5 |
5486039e85b7d78f6b636d47953daf62
|
|
| BLAKE2b-256 |
3378b19c9240177b95f84ba5edcdf85f36a2bb38d150274f641245d2caa4ebff
|