Python 3.15 Officially Released: Farewell to 3.10, Embracing 3.11 Features and the Lazy Loading Revolution

Python 3.15 brings lazy loading and a sampling profiler, and unlocks Python 3.11 modern features.
Python 3.15 has been officially released with several important updates to the language and standard library. PEP 810 explicit lazy imports allow modules to be truly loaded only on first use, greatly improving startup performance for CLI tools and plugin systems; PEP 798 comprehension unpacking lets list, set, and dictionary comprehensions unpack directly for clearer expression. The standard library adds the Tachyon high-frequency sampling profiler and the profiling.sampling namespace, enabling low-overhead performance analysis without third-party tools. Meanwhile, Python 3.10 has reached end of support, so maintainers can confidently use 3.11's tomllib, asyncio TaskGroup, datetime.UTC, and multiple SQLite enhancements. Performance-wise, 3.15 is essentially on par with 3.14, with only the experimental JIT showing roughly a 1.2x improvement for the first time. Overall, this is a release that emphasizes both feature enhancements and ecosystem unlocking.
The official release of Python 3.15 marks a significant turning point in the Python ecosystem. This version not only brings exciting new features, but also means that Python 3.10 has officially reached the end of its support cycle, allowing developers to confidently embrace the modern features introduced in Python 3.11.
For developers maintaining open-source projects, version iteration has always been a double-edged sword—you need to ensure your code runs correctly on all supported versions, yet you crave the conveniences that newer versions bring. With the release of 3.15, that balance point has finally shifted.
According to the official Python documentation, the What's New guide for 3.15 was curated by Hugo van Kemenade, release manager for both 3.14 and 3.15, and it includes several notable language-level improvements.

Explicit Lazy Loading: The Performance Breakthrough from PEP 810
One of the most anticipated features in Python 3.15 is explicit lazy imports from PEP 810. This mechanism allows developers to defer module imports in an extremely intuitive way:
lazy import json
lazy from pathlib import Path
Modules are only actually imported when the relevant symbols are first used in subsequent code.
The real value of this feature goes far beyond the surface. Take the LLM CLI tool developed by Simon Willison as an example—the tool supports a plugin system, and some plugins depend on heavyweight libraries like sentence_transformers. Before lazy loading existed, simply installing these plugins would add several seconds to the startup time of every llm command execution. Developers had to recommend manual lazy-loading tricks in their plugin authoring documentation. Now, native language-level support completely solves this pain point.
For developers building CLI tools and large applications, this means a significant improvement in startup performance while keeping code clean and concise.
PEP (Python Enhancement Proposal) is the formal documentation mechanism the Python community uses to propose, discuss, and record changes to the language or standard library. Every new syntax, new module, or behavior adjustment typically goes through public review as a PEP before core developers decide whether to adopt it. The PEP number itself does not represent priority; it is assigned in order of submission—for example, PEP 810 and PEP 798 mentioned in this article are both specific feature proposals.
For developers, PEP documents are the primary source for understanding the design motivation, boundary conditions, and compatibility impact of a feature. They typically include sections such as abstract, motivation, specification, and backward compatibility discussion. When evaluating whether to adopt a new feature in your project, consulting the corresponding PEP directly is often more reliable than secondhand tutorials, because it clearly states which interpreter versions the feature is available in and whether there are any unexpected runtime behaviors.
Comprehension Unpacking and a Sampling Profiler
The comprehension unpacking syntax introduced by PEP 798 brings a more elegant way to express data processing. The new syntax allows unpacking operations to be used directly within list, set, and dictionary comprehensions:
lists = [[1, 2], [3, 4], [5]]
[*L for L in lists]
Performance profilers are generally divided into two categories: tracing and sampling. Tracing profilers like `cProfile` hook and record events such as function calls and returns one by one, so their statistics are precise, but they significantly slow down program execution, and results are easily affected by the instrumentation itself. Sampling profilers instead capture call stack snapshots at fixed time intervals and estimate the proportion of time spent in each function based on the sample distribution, with overhead small enough that they can be used near production workloads.
The trade-off of sampling analysis is limited time resolution: extremely short-running functions may be missed, leading to statistical bias. Therefore it is better suited for discovering "hot paths" rather than for precise timing. Flame graphs are a common visualization for sampling analysis—the horizontal axis reflects sample proportion, and the vertical axis reflects call depth, intuitively exposing the call chains where time is concentrated. Tachyon, as a high-frequency sampler built into the standard library, means you can perform low-interference diagnostics on a running process without installing third-party tools or modifying code.
# Result: [1, 2, 3, 4, 5]
This syntax is equivalent to a comprehension with nested loops, but is more readable and expresses intent more clearly. The proposal was put forward by Adam Hartz and Erik Demaine, and is a natural extension of the unpacking syntax from PEP 448 in Python 3.5 (2015).
Another major update is a new sampling profiler in the standard library. The existing tracing profiler cProfile was renamed to profiling.tracing, while a high-frequency statistical sampling profiler called Tachyon was introduced as profiling.sampling.
The sampling profiler calculates function timing by periodically capturing stack traces of a running process, with extremely low overhead and no need for prior instrumentation. Developers previously needed third-party tools like py-spy to get this capability; now it is part of the standard library. For a running Python 3.15 process with a known PID, you simply run:
sudo uv run --python 3.15 python -m profiling.sampling attach 1234
The sampler generates reports containing detailed information such as sample counts, sampling percentages, and cumulative time, and can output flame graphs and heatmaps, even supporting the Firefox Profiler UI format.
Performance Comparison and Upgrade Path
Performance Differences Between 3.15 and 3.14
According to developer Miguel Grinberg's tests on version 3.15.0rc3, Python 3.15's overall performance is essentially on par with 3.14, with the only exception being the experimental JIT. In the Fibonacci test, the JIT delivered a 1.2x performance improvement over the standard interpreter—the first time Miguel observed a meaningful JIT performance improvement.
Looking back at Miguel's earlier tests of 3.14, that version showed significant improvements over Python 3.13 across multiple categories. This means 3.15 is more of a feature-enhancement release than a performance-leap release.
JIT (Just-In-Time compilation) refers to dynamically compiling hot bytecode into machine code during program execution to reduce the overhead of interpretation. CPython has long been primarily interpreter-based, and JIT has been a direction the community has pursued but advanced slowly. The experimental JIT introduced in Python 3.13 uses a "copy-and-patch" strategy, gradually translating specialized interpreter instructions into machine code rather than building a complete compiler from scratch.
"Experimental" means it may not be enabled by default, and the implementation is still evolving, potentially involving compilation overhead, memory usage, or behavioral differences. Therefore, when evaluating JIT benefits, it's important to distinguish between the standard interpreter and the JIT-enabled performance. Pure computation benchmarks like Fibonacci primarily measure function calls and arithmetic loops, and may not represent real applications that are I/O-intensive or depend on C extensions. The first meaningful improvement from JIT is a positive signal, but there is still a distance to go before it fundamentally changes the performance landscape.
Upgrading to Python 3.15 with uv
For developers using uv to manage Python environments, the upgrade process is quite straightforward. First, update uv itself to ensure it recognizes the new version:
uv self update
uv python install 3.15
uv python pin --global 3.15
The last command sets 3.15 as the default version for all uv run commands, unless a project itself pins a different version. For tools installed via uv tool install, you can use uv tool upgrade datasette --python 3.15 to reinstall and specify the Python version.
Embracing Python 3.11: Features You Can Finally Use
The release of Python 3.15 means Python 3.10, released in 2021, has officially reached end of support. For open-source project maintainers who insist on running code on all supported versions, this marks an important moment of unlocking.
New Additions to the Standard Library
The tomllib module can finally be used with confidence. This TOML parsing library introduced in 3.11 has already become a dependency for many projects, and now there is no need for extra handling for 3.10 compatibility.
For projects that heavily use asyncio, such as Datasette, features introduced in 3.11 like TaskGroup and timeout() will greatly simplify the writing of concurrent code. The datetime.UTC alias also makes timezone handling more concise.
Significant Enhancements to SQLite Support
Python 3.11 brought several important upgrades to SQLite support, and these improvements are especially critical for data-intensive applications:
setlimit()andgetlimit()methods allow setting SQLite runtime limits from the Python levelcreate_window_function()supports creating custom window functions with Python classes, requiring only the implementation ofstep(),value(),inverse(), andfinalize()methodsblobopen()provides an efficient mechanism for partial reads and writes of large BLOB binary valuesset_authorizer(None)can now remove the SQLite authorizer, for which the Datasette project previously maintained a workaround
Additionally, Python 3.11 has numerous improvements to the type hinting system, all of which will gradually benefit the entire ecosystem.
Ecosystem Impact and Outlook
The release of Python 3.15 is not merely an increment in version numbers; it represents a shift in development paradigms. Lazy loading solves the startup performance issues that have long plagued CLI tools and plugin systems, the sampling profiler in the standard library lowers the barrier to performance tuning, and the unlocking of 3.11 features gives developers more freedom to use the expressive power of modern Python.
For open-source project maintainers, now is the best time to plan an upgrade path. It is recommended to first update project configuration through cookiecutter templates, expand the test matrix to Python 3.11 through 3.15, and then gradually remove compatibility code for older versions.
Simon Willison has already taken the first step—his Datasette project is removing the set_authorizer(None) workaround, while template projects such as click-app, datasette-plugin, python-lib, and llm-plugin have all been updated to test against Python 3.11 through 3.15.
Python 3.15 may not be a performance-leap release, but the developer experience improvements and ecosystem-unlocking effects it brings will continue to manifest over the coming months and even years.
One-line Summary
Python 3.15 brings lazy loading and a sampling profiler, and unlocks 3.11 modern features.
Paragraph Summary
Python 3.15 has been officially released, bringing several important updates to the language and standard library. PEP 810 explicit lazy loading allows modules to be truly imported only on first use, significantly improving startup performance for CLI tools and plugin systems; PEP 798 comprehension unpacking allows list, set, and dictionary comprehensions to unpack directly, making expressions clearer. The standard library adds the Tachyon high-frequency sampling profiler and introduces the profiling.sampling namespace, enabling low-overhead performance analysis without third-party tools. Meanwhile, Python 3.10 has reached end of support, so maintainers can confidently use 3.11's tomllib, asyncio TaskGroup, datetime.UTC, and several SQLite enhancements. In terms of performance, 3.15 is essentially on par with 3.14, with only the experimental JIT showing roughly a 1.2x improvement for the first time. Overall, this is a release that emphasizes both feature enhancements and ecosystem unlocking.
Related articles

Free Unlimited Claude Code Solution: Agnes AI + CC Switch Setup Guide
No paid subscription needed — pair the free AI platform Agnes AI with the open-source tool CC Switch to provide a backend for Claude Code, enabling unlimited free calls to text, image, and video models. This guide covers the full setup, test results, and usage boundaries.

A Complete Zero-Cost Guide to Getting Started with Claude Code for Beginners in China
A beginner's guide to Claude Code for users in China: two installation methods (command line and IDE plugin), full configuration steps for replacing the official API with the free domestic LongCat model, and a hands-on demo of building a small tool with natural language, plus tips.

When the NSA Gets Involved: The AI Supply Chain Crisis Behind Open-Source CVEs and API Key Hijacking
Multiple open-source projects disclosed severe CVEs in one day, PHP flaws alarmed the FBI, and Railway and OpenCode were breached with API keys stolen. This article breaks down the vulnerability window, AI-accelerated exploitation, and the AI supply chain crisis behind the API key black market, with a developer defense checklist.