Skip to main content

Ultralytics logo

⚡️ autoimport: Explicit Lazy Module Imports

autoimport defers execution of a Python module until its first attribute access. It builds on Python's standard importlib loader protocol, preserving the canonical module object and its identity in sys.modules.

The ultralytics-autoimport package supports Python 3.8 through 3.14.

autoimport CI Ultralytics Actions PyPI - Version Downloads PyPI - Python Version

Installation

pip install ultralytics-autoimport

Usage

Replace a module import with an explicit lazy assignment:

import time

from autoimport import lazy_import

t0 = time.perf_counter()
torch = lazy_import("torch")  # Finds torch now, but does not execute torch/__init__.py yet
print(f"Setup: {time.perf_counter() - t0:.3f}s")

t1 = time.perf_counter()
torch.cuda.is_available()  # First attribute access executes and initializes torch
print(f"First use: {time.perf_counter() - t1:.3f}s")

torch.tensor([1, 2, 3])  # Later attributes use the fully initialized module normally

Aliases and dotted modules are explicit strings:

np = lazy_import("numpy")
linalg = lazy_import("numpy.linalg")

If the requested module is already imported, lazy_import() returns the existing object unchanged. Module discovery happens immediately, so a misspelled or unavailable module raises ModuleNotFoundError at the lazy_import() call. For dotted names, Python may import parent packages while finding the requested child module.

Scope and Limitations

lazy_import() deliberately supports modules only. It does not emulate arbitrary from ... import ... bindings:

# Supported
pathlib = lazy_import("pathlib")
path = pathlib.Path("models")

# Not provided: transparent lazy classes, functions, or constants
# Path = lazy_import("pathlib.Path")

Deferring a module also defers its import-time side effects and any exception raised while executing its body. Those effects or errors occur on first attribute access instead of at the assignment. If code immediately accesses the module after lazy_import(), there is no startup benefit.

First execution of lazy module bodies is serialized process-wide. This prevents two lazy modules from deadlocking each other during concurrent circular initialization, but it also means unrelated first accesses cannot initialize in parallel. Module bodies run while that shared reentrant lock is held, so applications should avoid coordinating lazy first access with other threads during import-time synchronization.

The discovered loader must support exec_module(), and its module object must permit __class__ reassignment. These are the same compatibility requirements as Python's importlib.util.LazyLoader; incompatible custom loaders fail during lazy_import() instead of returning a partial proxy.

Versions before 0.1.0 exposed a with lazy(): context manager that replaced builtins.__import__. That design could not preserve normal Python behavior for aliases, function-local imports, dotted imports, or objects imported with from ... import ..., and it affected imports in every thread. Replace it with explicit module assignments.

Python 3.15 and PEP 810

Python 3.15 adds native lazy imports through accepted PEP 810. Its interpreter-supported syntax can lazily bind both modules and imported attributes:

lazy from pathlib import Path

lazy import torch

PEP 810 also provides a migration form that keeps ordinary import statements:

>>> __lazy_modules__ = {"numpy", "torch"}
>>> import numpy as np
>>> import torch

On Python 3.15, the listed imports are lazy. Earlier Python versions ignore __lazy_modules__ and import them eagerly, which lets libraries adopt the declaration before dropping older versions. Native lazy imports are the preferred long-term solution because the interpreter can replace a lazy binding with any real module, class, function, or constant before Python code uses it. autoimport remains a narrow module-only option for Python 3.8 through 3.14.

Development

uv pip install -e .
python -m unittest discover tests -v
ruff format .
ruff check .

License

Ultralytics offers AGPL-3.0 and Enterprise licenses. See LICENSE and the Ultralytics licensing page.

For bug reports and feature requests, open a GitHub issue.

Download files

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

Source Distribution

ultralytics_autoimport-0.1.0.tar.gz (46.3 kB view details)

Uploaded Source

Built Distribution

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

ultralytics_autoimport-0.1.0-py3-none-any.whl (29.7 kB view details)

Uploaded Python 3

File details

Details for the file ultralytics_autoimport-0.1.0.tar.gz.

File metadata

  • Download URL: ultralytics_autoimport-0.1.0.tar.gz
  • Upload date:
  • Size: 46.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for ultralytics_autoimport-0.1.0.tar.gz
Algorithm Hash digest
SHA256 0ca669e339dadd8f3fbff475b91e4b288ba2098258b871094fb6d42c27102df6
MD5 ec6121c660220580cb4cfde5580a9c4d
BLAKE2b-256 e11860a0772e6c0f2f1b9c32cd971376f572f330f1599ccc1de14ce299604e09

See more details on using hashes here.

Provenance

The following attestation bundles were made for ultralytics_autoimport-0.1.0.tar.gz:

Publisher: publish.yml on ultralytics/autoimport

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

File details

Details for the file ultralytics_autoimport-0.1.0-py3-none-any.whl.

File metadata

File hashes

Hashes for ultralytics_autoimport-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 82c3b7dac1f33c90ae84ed12be38bcc95dceb883f092d2489ba1b360a781c4ec
MD5 ff6f6936cf147a92a87541480ca46465
BLAKE2b-256 9200eca985c2297a6a4efe7bb2d60be0dfb687aea7aa647235d4dc674fcc1248

See more details on using hashes here.

Provenance

The following attestation bundles were made for ultralytics_autoimport-0.1.0-py3-none-any.whl:

Publisher: publish.yml on ultralytics/autoimport

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

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 files

0.0.4

2 files

0.0.3

2 files

0.0.2

2 files

0.0.1

2 files

0.0.0

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page