Skip to main content

Makes it easy to load subpackages and functions on demand.

Project description

PyPI Test status Test coverage

lazy-loader makes it easy to load subpackages and functions on demand.

Motivation

  1. Allow subpackages to be made visible to users without incurring import costs.
  2. 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.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

lazy_loader-0.5.tar.gz (15.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

lazy_loader-0.5-py3-none-any.whl (8.0 kB view details)

Uploaded Python 3

File details

Details for the file lazy_loader-0.5.tar.gz.

File metadata

  • Download URL: lazy_loader-0.5.tar.gz
  • Upload date:
  • Size: 15.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for lazy_loader-0.5.tar.gz
Algorithm Hash digest
SHA256 717f9179a0dbed357012ddad50a5ad3d5e4d9a0b8712680d4e687f5e6e6ed9b3
MD5 c118985a3f8cc7d91a8b160002ba551f
BLAKE2b-256 49ac21a1f8aa3777f5658576777ea76bfb124b702c520bbe90edf4ae9915eafa

See more details on using hashes here.

Provenance

The following attestation bundles were made for lazy_loader-0.5.tar.gz:

Publisher: release.yml on scientific-python/lazy-loader

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file lazy_loader-0.5-py3-none-any.whl.

File metadata

  • Download URL: lazy_loader-0.5-py3-none-any.whl
  • Upload date:
  • Size: 8.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for lazy_loader-0.5-py3-none-any.whl
Algorithm Hash digest
SHA256 ab0ea149e9c554d4ffeeb21105ac60bed7f3b4fd69b1d2360a4add51b170b005
MD5 1b7f228e8c1c7d745ae0e45d9fe33960
BLAKE2b-256 8aa18d812e53a5da1687abb10445275d41a8b13adb781bbf7196ddbcf8d88505

See more details on using hashes here.

Provenance

The following attestation bundles were made for lazy_loader-0.5-py3-none-any.whl:

Publisher: release.yml on scientific-python/lazy-loader

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page