This release is a pre-release and may not be stable for production use.
lazy-loader makes it easy to load subpackages and functions on demand.
Motivation
- Allow subpackages to be made visible to users without incurring import costs.
- Allow external libraries to be imported only when used, improving import times.
For a more detailed discussion, see the SPEC.
Installation
pip install -U lazy-loader
We recommend using lazy-loader with Python >= 3.11.
If using Python 3.11, please upgrade to 3.11.9 or later.
If using Python 3.12, please upgrade to 3.12.3 or later.
These versions avoid a known race condition.
Usage
Lazily load subpackages
Consider the __init__.py from scikit-image:
subpackages = [
...,
'filters',
...
]
import lazy_loader as lazy
__getattr__, __dir__, _ = lazy.attach(__name__, subpackages)
You can now do:
import skimage as ski
ski.filters.gaussian(...)
The filters subpackages will only be loaded once accessed.
Lazily load subpackages and functions
Consider skimage/filters/__init__.py:
from ..util import lazy
__getattr__, __dir__, __all__ = lazy.attach(
__name__,
submodules=['rank'],
submod_attrs={
'_gaussian': ['gaussian', 'difference_of_gaussians'],
'edges': ['sobel', 'scharr', 'prewitt', 'roberts',
'laplace', 'farid']
}
)
The above is equivalent to:
from . import rank
from ._gaussian import gaussian, difference_of_gaussians
from .edges import (sobel, scharr, prewitt, roberts,
laplace, farid)
Except that all subpackages (such as rank) and functions (such as sobel) are loaded upon access.
Type checkers
Static type checkers and IDEs cannot infer type information from
lazily loaded imports. As a workaround you can load type
stubs (.pyi
files) with lazy.attach_stub:
import lazy_loader as lazy
__getattr__, __dir__, _ = lazy.attach_stub(__name__, "subpackages.pyi")
Note that, since imports are now defined in .pyi files, those
are not only necessary for type checking but also at runtime.
The SPEC describes this workaround in more detail.
Early failure
With lazy loading, missing imports no longer fail upon loading the
library. During development and testing, you can set the EAGER_IMPORT
environment variable to "1" or "true" to disable lazy loading ("0" or "" re-enables lazy loading).
External libraries
The lazy.attach function discussed above is used to set up package
internal imports.
Use lazy.load to lazily import external libraries:
sp = lazy.load('scipy') # `sp` will only be loaded when accessed
sp.linalg.norm(...)
Note that lazily importing subpackages,
i.e. load('scipy.linalg') will cause the package containing the
subpackage to be imported immediately; thus, this usage is
discouraged.
You can ask lazy.load to raise import errors as soon as it is called:
linalg = lazy.load('scipy.linalg', error_on_import=True)
Optional requirements
One use for lazy loading is for loading optional dependencies, with
ImportErrors only arising when optional functionality is accessed. If optional
functionality depends on a specific version, a version requirement can
be set:
np = lazy.load("numpy", require="numpy >=1.24")
In this case, if numpy is installed, but the version is less than 1.24,
the np module returned will raise an error on attribute access. Using
this feature is not all-or-nothing: One module may rely on one version of
numpy, while another module may not set any requirement.
Note that the requirement must use the package distribution name instead
of the module import name. For example, the pyyaml distribution provides
the yaml module for import.
Release files for lazy-loader 0.6rc0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| lazy_loader-0.6rc0.tar.gz | 18.4 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| lazy_loader-0.6rc0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 27.2 kB
Release files / lazy_loader-0.6rc0.tar.gz
| Download URL | lazy_loader-0.6rc0.tar.gz |
|---|---|
| Size | 18.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
056e1ed2ea26e56d7d5959eb6f9cec96c056c999227e20a73b90eeadaeb0f63e
|
|
BLAKE2b-256 checksum How to use checksums |
ee5c3a70176bf694570ebb42742e2a6f4c669c8b279981afa1dee28e53eec1bc
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 21, 2026.
Transparency logRelease files / lazy_loader-0.6rc0-py3-none-any.whl
| Download URL | lazy_loader-0.6rc0-py3-none-any.whl |
|---|---|
| Size | 8.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
60c4c7666c642493bec21e4bd7eb05f7f32da05b6abc1e5d012ba1f87123ef8e
|
|
BLAKE2b-256 checksum How to use checksums |
b4b3c2fd03a7947a4705617d396e899636dfd4cb5afedb6f15de2cde24bf63cf
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 21, 2026.
Transparency log