Python 3.15 Ships: Lazy Imports, frozendict, Faster JIT Python 3.15 has shipped with lazy imports via PEP 810, a built-in frozendict type via PEP 814, a standard-library sampling profiler codenamed Tachyon, and JIT improvements for compute-heavy code. PEP 810 reports 50–70% startup time reductions and 30–40% memory savings in large applications, and a Google demonstration on the google-cloud-compute library cut startup imports from 1,407 modules to 15. The release also changes behavior developers must test: lazy-imported modules raise errors at first use rather than at startup, and frozendict inherits directly from object, so isinstance(fd, dict) returns False. Python 3.15 is out, and the release notes are worth reading beyond the changelog. Lazy imports land as an explicit language feature — not a third-party hack — and in real applications they reduce startup time by up to 70%. A built-in frozendict type eliminates years of PyPI workarounds. A production-grade sampling profiler ships in the standard library. The JIT actually moves the needle on compute-heavy code. This is the release where CPython stops apologizing for startup cost and import bloat. Lazy Imports: The Feature Python Developers Have Been Waiting For Python 3.15 introduces the lazy soft keyword via PEP 810 https://peps.python.org/pep-0810/ . Write lazy import numpy and NumPy does not load until the first line that actually uses it. The module loads on first reference — a process called reification — not at import time. python lazy import numpy as np loads only when np is first referenced lazy import tensorflow as tf same def train data : return tf.keras.Sequential ... tf loads here, not at startup The numbers are striking. When Google demonstrated PEP 810 on the google-cloud-compute library, startup imports dropped from 1,407 modules to 15. PEP 810 itself reports 50–70% startup time reductions in large applications, with 30–40% memory savings. CLI tools, Django projects, and test suites are the immediate winners. Two things to understand before adopting it everywhere. First, the design is intentionally granular: only imports explicitly marked lazy are deferred. Libraries do not get lazy behavior unless their authors opt in. Second, import errors surface at first use, not at startup. If a lazy-imported module does not exist, you find out the moment your code tries to use it — not when the application starts. That is a behavior change worth testing before shipping to production. The backward compatibility story is clean: on Python 3.14 and earlier, the lazy declaration is silently ignored and the import runs eagerly. You can adopt the syntax today without breaking older environments. frozendict: A Built-In Immutable Dict, Finally The frozendict PyPI package has been downloaded tens of millions of times. Python developers have wanted an immutable, hashable dict since at least 2012. PEP 416 https://peps.python.org/pep-0416/ tried and was rejected. PEP 814 succeeded, and frozendict ships as a built-in in 3.15. config = frozendict {"host": "localhost", "port": 5432} Use as a dict key cache = {config: result} Use in a set seen = {config} Use as an lru cache argument @functools.lru cache def connect params: frozendict - Connection: ... A frozendict is not a subclass of dict — it inherits directly from object . That means isinstance fd, dict returns False . Existing code that type-checks with isinstance x, dict will not automatically accept a frozendict . Worth auditing before you refactor your codebase to use it everywhere. Beyond caching, the practical use cases are config objects that should not mutate after construction, thread-safe read-only mappings no locks needed , and function default arguments that do not share state across calls. If you have been using types.MappingProxyType as a workaround, note that proxy is not hashable — frozendict is. Tachyon: A Production Profiler Ships in stdlib Python profiling has been awkward for years. cProfile is built in but adds 20–40% runtime overhead. Production profiling required third-party tools like py-spy https://github.com/benfred/py-spy or Austin that you had to install, configure, and justify to your security team. Python 3.15 ships profiling.sampling — codenamed Tachyon — a statistical sampling profiler with near-zero overhead that can attach to already-running processes. Profile a running process without restarting it python -m profiling.sampling attach 12345 Generate a flame graph from a script python -m profiling.sampling run --flamegraph slow script.py Live top-style view python -m profiling.sampling run --live server.py Tachyon samples at up to 1,000,000 Hz and outputs interactive HTML flame graphs natively, without extra tooling. PEP 799 also reorganizes the existing profiling landscape: profiling.tracing is cProfile under a new, logical home. For teams that have been shipping py-spy alongside their applications to enable production profiling, this is now a stdlib capability. JIT: Real Gains, Honest Limitations Python 3.15 JIT compiler uses LLVM 21 for stencil generation and adds basic register allocation, reducing stack operations on hot paths. The pyperformance https://pyperformance.readthedocs.io/ benchmark suite shows a 7–8% geometric mean improvement on x86-64 and 11–12% on AArch64. The Mandelbrot benchmark specifically dropped from 5.25 seconds to 2.47 seconds — roughly 2x on that workload. Ten of twelve pyperformance benchmarks are faster. Two are marginally slower. The JIT benefits code that spends time in pure Python computation — scientific computing, numerical preprocessing, algorithmic Python. If your code is I/O-bound, dominated by calls into C extensions, or mostly handled by an async event loop, the JIT gains will not show up. That is not a knock on the work; it is just what JIT compilers do. Before You Upgrade: What Actually Breaks Python 3.15 biggest migration hazard is not a feature — it is a default behavior change. The release finalizes UTF-8 as the default encoding for open , read text , write text , and stdio. Any code that implicitly relied on Windows code pages or platform-native encodings will break silently or raise errors. Run this before upgrading: python -X warn default encoding -m pytest Fix every open and read text call that lacks an explicit encoding= argument. This matters most on Windows and when processing files written by legacy systems. - distutils is gone — migrate to setuptools , flit , or hatch if you have not already - asyncio.get event loop deprecation tightens — switch to asyncio.run or explicit loop creation - importlib.metadata now raises MetadataNotFound instead of returning empty metadata - argparse enables suggest on error=True by default To install Python 3.15 today, the fastest path is uv https://docs.astral.sh/uv/ : uv python install 3.15 uv venv --python 3.15 Lazy imports are the headline, but the broader picture here is that Python is systematically addressing its long-standing criticisms: startup cost, immutable data types, and production observability. The ecosystem is overdue to treat these as first-class concerns. Python 3.15 makes that a lot easier. Full details in the official What is New in Python 3.15 https://docs.python.org/3.15/whatsnew/3.15.html .