Evidence at a glance

Python 3.15.0 2026 10 9 。Evidence
Python 3.10 2026 10 1 。Evidence
Python 3.10 2021 , 。Evidence
Python 3.15 3.14 。Evidence
JIT 1.2x。Evidence
sentence_transformers llm 。Evidence

Two Version Milestones, Two Different Decisions

The Python project released Python 3.15.0 on October 9, 2026. The release adds explicit lazy imports, unpacking in comprehensions, and a new sampling profiler, touching startup cost, code expression, and performance diagnosis. In his account of the release, Simon Willison also says that his open-source projects will drop Python 3.10 and begin using features from 3.11.

Those two moves happened close together, but they are not the same decision. Python 3.10 reached end of life on October 1, and whether to stop supporting it is a project-level compatibility choice; the arrival of 3.15 does not require every project to upgrade. For a technical lead, the useful question is not simply whether to chase the latest version, but whether the minimum supported version should move with the support cycle and whether doing so will pay off in maintenance.

Lazy Imports Defer Startup Cost; They Do Not Erase It

Willison's example comes from an LLM command-line tool with plugins. If a plugin depends on a heavy library such as `sentence_transformers`, importing it can add seconds to every invocation, even when that command never uses the plugin's functionality. Until now, he could only advise plugin authors to defer imports manually. Python 3.15's PEP 810 lets code state that choice directly with forms such as `lazy import json` or `lazy from pathlib import Path`.

A marked module first appears as a lightweight proxy and is loaded only when later code uses the relevant name. Plugin paths that are never taken can therefore avoid paying their import cost at startup. But the cost has not vanished; it has moved to the first call that needs the module. Import failures are deferred too, and because `lazy` is restricted to module scope, the feature changes not only startup behavior but also when failures surface and what tests need to exercise.

Diagnosis Moves into the Standard Library, but Speed Claims Need Restraint

Python 3.15 also brings sampling profiling into the standard library. Tachyon periodically captures stack traces from a running process and uses them to estimate which functions consume the most time. Unlike approaches that require prior instrumentation, it can attach to an existing Python 3.15 process. Willison's example entry point is `python -m profiling.sampling attach <PID>`; after collection, it can produce a report, flame graphs, heat maps, or data for the Firefox Profiler interface.

The operational benefit is a lower barrier to observing a workload before changing its code, not an automatic root-cause analysis. Tachyon can help a team identify hotspots worth investigating, but the samples still need to be interpreted in context. Nor do the performance figures justify presenting 3.15 as a general speed upgrade: tests against 3.15.0rc3 found performance broadly similar to 3.14. The experimental JIT was 1.2 times faster than the standard interpreter on a Fibonacci test, a result limited to that test and experimental implementation.

What a Higher Compatibility Floor Buys

Once Willison drops 3.10, he can set 3.11 as the minimum and use standard-library capabilities added in that release. `tomllib` parses TOML; `asyncio.TaskGroup` and `asyncio.timeout()` support task groups and timeouts; and `datetime.UTC` provides a convenient name for the UTC timezone. Python 3.11 also expanded its SQLite interface with methods including `setlimit()`, `getlimit()`, `create_window_function()`, and `blobopen()`. For maintainers, these capabilities may reduce extra dependencies or custom code, but only if users can accept the higher minimum version.

That is why using 3.15 locally and supporting projects from 3.11 can coexist. Willison set 3.15 as his global default with `uv`, while a project that pins another version still takes precedence; he also changed several project templates to test Python 3.11 through 3.15. A global default serves day-to-day development, while a project's minimum version defines its compatibility promise. Raising that floor leaves behind users who still need 3.10, so maintainers should check user requirements, dependency compatibility, and test coverage rather than treating a new release as an automatic upgrade order.

Make the Upgrade Decision Against Real Workloads

The most practical changes in Python 3.15 give maintainers more choices to incorporate into engineering decisions: load plugin dependencies on demand, sample a running process for diagnosis, and revisit compatibility floors when support periods end. Unpacking in comprehensions is a more local improvement. It makes some nested-comprehension and `itertools.chain()`-style expressions more direct, but on its own is not a reason to migrate.

If a team's main problem is CLI cold-start time, it can first identify modules unused on common command paths, evaluate lazy imports, and add tests for failures that will now occur later. If the problem is limited visibility into production performance, the sampling profiler provides a standard-library entry point, but its data still needs to be interpreted against real workloads. Whether to raise the minimum version should be decided by weighing support timelines, user needs, and maintenance cost together. Python 3.15 does not supply one answer for every project; it gives maintainers clearer tools for making the trade-offs.