On 1 September 2026, Python 3.15 cleared its last milestone before launch: the 3.15.0rc2 release candidate, now feature-frozen. The final version is due on 1 October. Three changes stand out for web back-ends: explicit lazy imports, UTF-8 as the default encoding, and a substantially reworked JIT compiler.
A release candidate that is already frozen
rc2 closes the development phase: no further features will be added, and the ABI stays stable through to the final release. It bundles roughly 144 fixes reported since rc1 — a cycle now focused on stabilisation.
| Milestone | Date | Scope |
|---|---|---|
| 3.15.0rc1 | August 2026 | Feature freeze |
| 3.15.0rc2 | 1 September 2026 | Final RC, ABI frozen, ~144 fixes |
| 3.15.0 final | 1 October 2026 | Production release |
For teams running Python services in production, the testing window is closing: now is the time to validate dependencies against the RC, with the same production discipline — a systemd-managed service, a reverse proxy — as any other back-end.
PEP 810: lazy imports, but explicit
The most visible change is a new soft keyword, lazy. A module marked lazy is only loaded on first access to one of its attributes, cutting startup latency and the memory footprint of apps that import a lot without using everything.
lazy import json
lazy from pathlib import Path
print("...") # json et pathlib pas encore charges
data = json.loads('{"cle": "valeur"}') # json est charge ici
racine = Path(".") # pathlib est charge iciA compatibility mode exists through the __lazy_modules__ variable, handy for making imports lazy without rewriting each line. The gain is clearest on command-line programs, where launch time is paid on every invocation — familiar ground for CLI tooling.
The catch is in the word “explicit”: unlike an automatic mechanism, PEP 810 leaves the choice to the developer, import by import. Side effects triggered at import time — plugin registration, opening connections — must never be made lazy without analysis.
UTF-8 by default: the end of a silent bug source
With PEP 686, Python now uses UTF-8 as the default encoding, independent of the system environment. A call like open('data.txt') reads as UTF-8 with no configuration, ending behaviour gaps between a developer’s machine and a server whose locale differs.
The historical behaviour remains available: PYTHONUTF8=0 or the -X utf8=0 option restore locale-dependent encoding while the rare scripts that relied on it are migrated.
A file opened without specifying an encoding now reads as UTF-8, whatever the server: the main cause of environment drift is gone.
A reworked JIT and two new built-in types
The JIT compiler, experimental in earlier versions, has been “significantly upgraded” according to the release notes, which report gains of roughly 8–13% depending on the platform. The 64-bit Windows binaries also adopt the tail-calling interpreter. Like other ecosystems betting on execution speed, Python is working to cut the cost of interpretation.
On the type front, two additions land in builtins: frozendict, an immutable and hashable dictionary (PEP 814), and sentinel, for creating unique sentinel values with a readable representation (PEP 661).
>>> config = frozendict(hote="db.interne", port=5432)
>>> config["port"]
5432
>>> config["port"] = 5433
TypeError: 'frozendict' object does not support item assignmentWatch out. Lazy imports shift the loading cost to first access: an import exception no longer surfaces at startup but mid-execution. On a web service, a configuration error once caught at boot can turn into a production incident. Reserve lazy imports for heavy modules with no side effects.
Key takeaways
- Python 3.15 has been frozen since the 1 September rc2; the final version ships on 1 October 2026.
- PEP 810 brings explicit lazy imports (
lazy import), effective on startup of tools and apps. - PEP 686 makes UTF-8 the default, reversible via
PYTHONUTF8=0. - The JIT improves, and
frozendict/sentineljoin the built-in types.
Lazy imports are the feature I was waiting for most, but also the one that demands the most discipline. On my own services I’ll only enable them on heavy modules verified to have no side effects: an import that fails mid-request rather than at startup is the kind of surprise you pay dearly for on a Friday night. — Simon Janvier
Primary source: “What’s New In Python 3.15”, the official documentation, and the 3.15.0rc2 release candidate notes.
