
Python 3.15 RC1 shipped August 4. The feature set is now locked — every change described below ships in the stable release on October 1, 2026. RCs don’t add features; they chase bugs. If you ship Python apps and ignored the betas, this is the moment to run your test suite against RC1 and find out what breaks before it becomes someone else’s production incident.
Lazy Imports Are Now a Language Feature
PEP 810 adds the lazy soft keyword, and it does exactly what you’d hope: defers module loading until the imported name is actually used. The module never loads, never enters sys.modules, until something touches it.
# 3.15+: nothing loads until pd.DataFrame() is called
lazy import pandas as pd
lazy import torch
# Backward-compatible: ignored silently on Python < 3.15
__lazy_modules__ = ["pandas", "torch"]
import pandas as pd # lazy on 3.15, eager on older versions
This is a bigger deal than it sounds for CLI tools. A FastAPI app that imports heavy ML libraries only on certain routes, a Django management command that pulls in pandas for a single report — these have been paying a cold-start tax on every invocation. JetBrains already confirmed PyCharm 2026.2 will support the syntax. The isort project opened an issue to handle __lazy_modules__ ordering. The ecosystem is moving.
The Breaking Change You Need to Audit Now
PEP 686 makes UTF-8 the system default for all I/O, effective 3.15. That means open() without an explicit encoding argument now always uses UTF-8 — regardless of your OS locale, region settings, or what your server was configured with in 2009.
# This is now always UTF-8 — no more OS-locale roulette
with open("data.txt") as f:
content = f.read()
# If your file isn't UTF-8, you must say so
with open("legacy_report.txt", encoding="latin-1") as f:
content = f.read()
# Emergency escape hatch (not a long-term solution)
# PYTHONUTF8=0 python your_script.py
Who this hits hardest: Windows shops running Python on servers with legacy code pages, and anyone processing files from external systems that send Latin-1 or CP1252. If your CI is already on Linux with a UTF-8 locale, you may not see breakage until you hand code to a client running Windows Server 2019 with regional settings from a different decade. Audit every bare open() call. It’s grunt work, but it’s a one-time fix.
frozendict Lands in Builtins
Python finally has a built-in immutable dictionary. PEP 814 adds frozendict directly to builtins — no imports, no third-party package, no types.MappingProxyType workaround.
# frozendict is hashable, so it works as a dict key
config = frozendict(env="prod", region="us-east-1")
results_cache = {config: run_query(config)}
# Works with lru_cache now — previously impossible with a dict arg
@functools.lru_cache()
def render(template_vars: frozendict) -> str:
...
# Mutation raises TypeError immediately
config["env"] = "staging" # TypeError: frozendict does not support item assignment
One important detail: frozendict is not a subclass of dict. It inherits from object directly. Any code doing isinstance(x, dict) to accept a mapping will silently reject a frozendict. Library maintainers in particular should update those checks to isinstance(x, (dict, frozendict)) or, better, check for collections.abc.Mapping.
Production Profiling Is Now Stdlib
The profiling.sampling module — nicknamed Tachyon — is Python’s first zero-overhead statistical profiler in the standard library. It reads your process’s call stack externally, without instrumenting function calls, which means it can run in production without slowing down your application.
The practical difference from cProfile: Tachyon can attach to a running process with no restart and no code changes. The sampling rate goes up to 1,000,000 Hz. It handles async functions, free-threaded builds, and multi-threaded programs. The full docs are live on the 3.15 documentation site.
JIT: Real Progress, Still Not for Production
The 3.15 JIT is 8–9 percent faster on x86-64 Linux and 12–13 percent faster on AArch64 macOS versus the standard interpreter. The gains are real: the team rewrote the tracing frontend entirely, added basic register allocation, and increased JIT code coverage by 50 percent. But the JIT is still experimental — it still requires a --enable-experimental-jit build flag. Don’t enable it in production. The target for stable JIT is 3.16.
What to Do Right Now
Install RC1 in a virtual environment and run your test suite. The official What’s New page has the full list of deprecation removals and behavior changes. File bugs at the CPython issue tracker before September 1 — that’s when RC2 locks down. The window to influence what ships in October is open right now, and it won’t be open much longer.













