Updated 07:43
What Python froze on September 1
Four of 3.15's changes alter how existing code behaves, and each has an off switch. The JIT's benchmark box says the results are not final.
Python 3.15.0rc2 landed on September 1, and the release page is explicit about what that means: "This release, 3.15.0rc2, is the final planned release candidate, containing around 144 bugfixes, build improvements and documentation changes from 76 contributors since 3.15.0rc1." Then the sentence that matters to anyone who ships extensions: "There will be no ABI changes from this point forward in the 3.15 series, and the goal is that there will be as few code changes as possible." Wheels built now will keep working: "Any binary wheels built against Python 3.15.0 release candidates will work with future versions of Python 3.15." Final is "scheduled for 2026-10-01".
So the feature list is settled. Four of its entries change how existing programs behave, and the rest are additions.
The lazy keyword
PEP 810 adds lazy as a soft keyword in front of import. The What's New document describes the mechanism: "When you write lazy import heavy_module, Python does not immediately load the module. Instead, it creates a lightweight proxy object. The actual module loading happens transparently when you first access the name". Failures move with the load: "Python raises the exception at the point of first use rather than at import time. The associated traceback includes both the location where the name was accessed and the original import statement".
The restrictions are firm. "Lazy imports are only permitted at module scope; using lazy inside a function, class body, or try/except/finally block raises a SyntaxError." Star imports and __future__ imports cannot be lazy either.
There is a global switch, and this is where the behavior change hides. "Python provides the -X lazy_imports command-line option and the PYTHON_LAZY_IMPORTS environment variable. Both accept two values: all makes all imports lazy by default, and normal (the default) respects the lazy keyword in source code." Any module that relies on import-time side effects will misbehave under all, which is why there is also sys.set_lazy_imports_filter(), a callable that "should return True to allow the import to be lazy, or False to force eager loading." For code that must also run on 3.14, a module can list names in __lazy_modules__ and plain import statements for them become lazy.
UTF-8 by default, frame pointers by default
PEP 686 flips the encoding default: "Python now uses UTF-8 as the default encoding, independent of the system's environment. This means that I/O operations without an explicit encoding, for example, open('flying-circus.txt'), will use UTF-8." The escape hatch is PYTHONUTF8=0 or -X utf8=0. On a Linux server with a UTF-8 locale this changes nothing. On a Windows box with a legacy code page it changes every unqualified open().
PEP 831 turns on frame pointers: "CPython is now built with frame pointers by default on platforms that support them. This uses the compiler flags -fno-omit-frame-pointer and -mno-omit-leaf-frame-pointer". The document carries a warning for anyone building native extensions outside Python's own flags: "A single native component built without frame pointers can break stack unwinding for the whole Python process."
The JIT, with a caveat attached
The JIT section reports numbers and immediately qualifies them. "Results from the pyperformance benchmark suite report 8-9% geometric mean performance improvement for the JIT over the standard CPython interpreter built with all optimizations enabled on x86-64 Linux. On AArch64 macOS, the JIT has a 12-13% speedup over the tail calling interpreter with all optimizations enabled." Directly beneath, an attention box: "These results are not yet final."
Windows gets a separate speedup that does not need the JIT. "64-bit builds using Visual Studio 2026 (MSVC 18) may now use the new tail-calling interpreter. Results on Visual Studio 18.1.1 report between 15-20% speedup on the geometric mean of pyperformance on Windows x86-64 over the switch-case interpreter on an AMD Ryzen 7 5800X." The official python.org Windows binaries use it.
The rest of the list
PEP 799 adds a profiling package and Tachyon, a sampling profiler with rates "up to 1,000,000 Hz" and an attach mode for a running PID. PEP 814 adds frozendict to builtins; PEP 661 adds sentinel; PEP 798 allows unpacking in comprehensions; PEPs 803, 820 and 793 define a stable ABI for free-threaded builds.
One month remains. The release page asks maintainers to "prepare third-party projects for 3.15" and publish wheels on PyPI before October 1.
Primary sources: Python 3.15.0rc2 release page, Python Insider: 3.15.0 candidate 2, What's New in Python 3.15, What's New source, 3.15 branch, read 2026-09-04.