Python 3.15: Lazy Imports, frozendict, and a Faster JIT Python 3.15 shipped on October 9 with explicit lazy imports, a built-in frozendict type, and JIT improvements, per the release's PEP 810 and PEP 814 documentation. Meta's codebase saw a 70% reduction in initialization time after adopting lazy imports, which defer module loading until first use. The JIT compiler now shows 7–8% geometric mean improvement on x86-64 Linux and 11–12% on AArch64 macOS, up from roughly 2% in 3.13 and 4–5% in 3.14. Python 3.15 shipped on October 9. The headline feature is explicit lazy imports https://peps.python.org/pep-0810/ — a syntax change that defers module loading until first use. Meta’s codebase saw a 70% reduction in initialization time after adopting the pattern. The release also ships frozendict as a built-in type, a proper sentinel, unpacking in comprehensions, and a JIT compiler that is finally showing numbers worth quoting. Here is what matters and what to watch. Lazy Imports: The Startup Fix Python Needed For years, heavy Python apps had a startup problem. A web server importing Django, SQLAlchemy, and a handful of ML libraries could spend 400–800ms doing nothing but running import statements before accepting a single request. The standard fix was manual workaround: move imports inside functions, use importlib tricks, or fork CPython like Meta did. Python 3.15 makes this a first-class feature. The new lazy soft keyword defers module loading until the imported name is first accessed: python lazy import json lazy from pathlib import Path At this point, nothing is loaded — proxy objects only The real import fires on first use: data = json.loads '{"key": "value"}' For projects that need to stay compatible with older Python versions, there is a backwards-compatible approach using the lazy modules list. On Python 3.15+, those imports become lazy. On older versions, the list is ignored and imports proceed normally. python lazy modules = 'numpy', 'pandas', 'heavy analytics lib' import numpy import pandas The practical wins are real. CLI tools are the clearest example — when a user runs --help , there is no reason to import a plotting library or a database driver. Meta’s 70% initialization reduction was not a lab benchmark; it came from converting production libraries with deep dependency graphs. Two risks worth naming. First: late error detection. An ImportError that used to surface at startup will now surface when you first access the lazy import, potentially during request handling or a background job. Second: thread safety. Startup was previously single-threaded; now any thread that first touches a lazy import triggers the load. Neither is a dealbreaker, but both require awareness when adopting this pattern in concurrent systems. frozendict: A Built-in That Took 20 Years Python developers have needed an immutable, hashable dictionary for a long time. The standard library offered types.MappingProxyType as a partial answer, but it was a view over a mutable dict — not genuinely hashable, not usable as a dict key. Third-party packages filled the gap. Python 3.15 ships frozendict as a proper built-in via PEP 814 https://peps.python.org/pep-0814/ . python import functools config = frozendict {"model": "gpt-4o", "temperature": 0.7} Use as a cache key @functools.lru cache def run query cfg: frozendict - str: ... Use as a set member or dict key seen configs = {frozendict user="alice" , frozendict user="bob" } lookup = {frozendict scope="read" : handler fn} A few things to know before adopting it. frozendict is not a dict subclass — isinstance fd, dict returns False . That is intentional: it avoids inheriting mutation methods that would need to raise errors. The immutability is also shallow: a nested list inside a frozendict is still mutable, and a frozendict containing a list cannot be hashed. These are the same constraints that apply to frozenset , so the behavior is at least consistent. The JIT Keeps Compounding Python’s experimental JIT has been technically available since 3.13. It has not been worth enabling until now. Python 3.15 shows 7–8% geometric mean improvement on x86-64 Linux and 11–12% on AArch64 macOS, with upgrades to LLVM 21, a new tracing frontend, basic register allocation, and lower memory usage for generated machine code. The trajectory matters more than any single number: roughly 2% in 3.13, 4–5% in 3.14, 7–8% in 3.15. The JIT is still experimental and opt-in — it will not activate automatically. It is also not PyPy. But 8% on a distributed workload has real infrastructure cost implications, and the trend line is clearly heading somewhere. Smaller Wins Worth Knowing Python 3.15 also ships sentinel as a built-in. The old MISSING = object pattern works fine but produces ugly reprs and does not pickle cleanly. sentinel "MISSING" gives you a named, picklable, identity-preserving sentinel that works properly with type annotations. PEP 798 https://peps.python.org/pep-0798/ adds unpacking to comprehensions: Before Python 3.15 flat = x for sublist in lists for x in sublist Python 3.15 flat = sublist for sublist in lists Merge dicts in one comprehension merged = { d for d in dict list} What Actually Breaks UTF-8 is now the default encoding on all platforms. Code that calls open without an explicit encoding= argument and relies on locale defaults — especially on Windows — may produce different output. The fix is to pass encoding="utf-8" explicitly. Several long-deprecated APIs are now removed: datetime.utcnow use datetime.now datetime.UTC , importlib.resources.read text , and the internal sre compile , sre constants , sre parse modules. The regex internals are the most likely surprise — some packages accessed them directly. Check your dependencies before upgrading. The official What’s New page https://docs.python.org/3.15/whatsnew/3.15.html has the full list. Should You Upgrade? For greenfield projects: yes. The new built-ins are cleaner than their alternatives, and lazy imports are worth adopting for anything with non-trivial startup cost. For existing projects: check your dependencies first. The UTF-8 default and removed APIs are the likeliest sources of breakage, and most projects will need small fixes rather than rewrites. Python 3.15 is not a headline release — there is no walrus operator moment, no match statement. What it is: a release that fixes chronic annoyances that Python developers have been patching around for years. That is often more valuable than a flashy syntax addition. The official download is available now https://www.python.org/downloads/release/python-3150/ .