Skip to content

Use lazy imports on Python 3.15 to improve startup speed - #645

Merged
hugovk merged 1 commit into
jazzband:masterfrom
hugovk:lazy
Jun 19, 2026
Merged

Use lazy imports on Python 3.15 to improve startup speed#645
hugovk merged 1 commit into
jazzband:masterfrom
hugovk:lazy

Conversation

@hugovk

@hugovk hugovk commented Jun 16, 2026

Copy link
Copy Markdown
Member

Replaces and closes #608.

The upcoming Python 3.15 (now in beta) introduces a new lazy keyword for imports:

lazy import json

With this, the import doesn't actually happen until the first use:

json.dumps(thing)

So there's no need for the deferred method used in #608.

This is new syntax in 3.15, if you use it on an older version you get a syntax error. But there's a transitional mechanism: if you declare the imports in __lazy_modules__, they'll be treated as if they're lazy in 3.15+, and ignored for older versions.

Running with Python 3.15:

python3 -X importtime -c 'import tablib' 2> import.log
pip install tuna
tuna import.log

Before: 8 ms

image

After: ~0 ms

image

Even better than #608!

@codecov

codecov Bot commented Jun 16, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 93.19%. Comparing base (b8c6606) to head (4c09d9b).

Additional details and impacted files
@@            Coverage Diff             @@
##           master     #645      +/-   ##
==========================================
+ Coverage   93.16%   93.19%   +0.03%     
==========================================
  Files          29       29              
  Lines        3231     3247      +16     
==========================================
+ Hits         3010     3026      +16     
  Misses        221      221              

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@hugovk hugovk added the changelog: Added For new features label Jun 16, 2026
@claudep

claudep commented Jun 16, 2026

Copy link
Copy Markdown
Contributor

Interesting, really! I wonder however what's the cost of "hard" importing the Python's own modules, like io, decimal, operator. Aren't essentially external modules that are costly to import?

@hugovk

hugovk commented Jun 17, 2026

Copy link
Copy Markdown
Member Author

The light blue boxes in the top chart are stdlib modules, and we can see many of them are contributing real cost to the import tree.

As linked in #608, we've been deferring imports inside the stdlib of other stdlib modules to help reduce this cost, and in 3.15+ using the lazy keyword instead (for example, python/cpython#147992, python/cpython#149318, python/cpython#149416, python/cpython#146327). re is a common target.

The stdlib has some benefit: they're usually byte-compiled to pyc at install time, but that's a cheap one-time cost for external modules, and doesn't affect costly execution time. Some modules are always imported as part of site (but that can be disabled). Some bootstrap modules are "frozen" into the binary to avoid file lookup.

Looking the top chart again, most of the lower edge underneath tablib is light blue, so most of the import time comes from importing stdlib.

@claudep claudep left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the detailed explanations 😍

@hugovk
hugovk merged commit 64f0201 into jazzband:master Jun 19, 2026
22 of 24 checks passed
@hugovk
hugovk deleted the lazy branch June 19, 2026 09:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

changelog: Added For new features

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants