Python 3.15 Arrives: Lazy Imports, a Faster JIT, and UTF-8 by Default
The Python Software Foundation has released Python 3.15, and this year's annual CPython update is one of the most consequential in years. Arriving on October 9 after a slightly bumpy runway — the release manager even pushed out an unscheduled third release candidate to squash last-minute lazy-import bugs — Python 3.15 is less about a single headline feature and more about a performance story that is finally starting to compound.
Lazy Imports: The Feature Everyone Will Notice First
The change with the broadest day-to-day impact is PEP 810, explicit lazy imports. Python has always loaded imported modules eagerly, even when a program never touches them at runtime. For large applications with heavy dependency trees, that import tax has long dominated startup latency — a pain point familiar to anyone who has run a CLI tool that takes a second just to print a help message.
Python 3.15 introduces a new lazy soft keyword. Write lazy import heavy_module and Python defers loading the module until the first time your code actually uses it. Developers get the organizational benefit of declaring all imports at the top of a file while only paying the loading cost for the modules they truly exercise. If a lazily imported module fails to load, the exception is raised at the point of first use rather than at import time — a behavioral nuance that teams will want to account for in error handling.
The JIT Compiler Grows Up
The experimental just-in-time compiler introduced in recent CPython releases has received its most substantial upgrade yet. According to the release notes, the JIT now delivers a 7–8% geometric mean performance improvement over the standard interpreter on x86-64 Linux, and an 11–12% speedup on AArch64 macOS compared to the tail-calling interpreter. The numbers vary by platform and workload, and the JIT remains officially experimental — but the trajectory is unmistakable. CPython's multi-year performance push, from the specializing interpreter to the copy-and-patch JIT, is delivering measurable returns.
UTF-8 Everywhere
Python 3.15 also flips one of its longest-standing configuration defaults: UTF-8 is now the default encoding across platforms, per PEP 686. For years, cross-platform text handling trips over locale-dependent encodings, with Windows behaving differently from Linux and macOS. Defaulting to UTF-8 eliminates a whole class of cross-platform compatibility bugs and brings Python in line with the broader industry direction.
Free-Threading Takes Another Step
Work on removing the Global Interpreter Lock continues to mature. Python 3.15 adds a stable ABI for free-threaded builds, called abi3t, along with companion C API changes. The macOS installers now include free-threading support by default, making it dramatically easier for developers to experiment with GIL-free parallelism. Extension authors should note, however, that targeting the new ABI generally requires non-trivial source changes — the docs are candid that compatibility is not automatic.
Smaller Gems Worth Knowing
The release is packed with quality-of-life improvements:
- frozendict becomes a built-in type (PEP 814), giving developers an immutable, hashable mapping.
- A built-in sentinel type (PEP 661) finally standardizes a pattern libraries have reimplemented for decades.
- Unpacking in comprehensions (PEP 798) simplifies common iteration idioms.
- Package startup configuration files (PEP 829) let packages define declarative startup behavior.
- A new statistical profiler, Tachyon, can sample a live process without code modification or restarts and emit interactive flame graphs — a significant observability upgrade.
- Frame pointers are now enabled by default, improving integration with system-level profilers.
- Error messages and typing features continue their steady polish, with TypedDict gaining typed extra items and the argparse module enabling suggestion hints by default.
Should You Upgrade?
The honest answer: CPython performance work is compounding, but no single feature is a must-upgrade on its own. The JIT is not finished, free-threading is not yet mainstream, and the biggest wins come from measuring your own workloads. Teams with import-heavy CLI tools and services will likely see immediate startup improvements from lazy imports, while data-heavy shops should benchmark the JIT and free-threaded builds against their real dependencies.
As always with a fresh major release, the practical blocker is ecosystem compatibility. Give key libraries a few weeks to publish wheels, test your critical paths, and treat 3.15 as the release where Python's modernization efforts visibly converge.
One thing is clear: the world's most popular programming language is getting faster, leaner at startup, and more serious about parallelism — one deliberate annual release at a time.
What are your thoughts on Python 3.15? Will lazy imports change how you structure your code? Let us know in the comments.
Top comments (0)