Luke Oliff.

What Python 3.15 Changes, and What to Test Now

·Engineering·3 min read·Luke Oliff
TL;DR

Python 3.15.0rc2 shipped 1 September 2026, with final planned for 1 October. Free-threading is no longer experimental, lazy imports arrive via PEP 810, and UTF-8 becomes the default preferred encoding. The RC is the point to run your test suite against.

Python 3.15.0rc2 shipped on 1 September 2026, with the final release planned for 1 October. The short version of the python 3.15 changes worth caring about now: free-threading is no longer experimental, lazy imports arrive as an opt-in via PEP 810, and UTF-8 becomes the default preferred encoding. The release candidate is where you start testing, because the API is frozen and only bug fixes land before final.

I moved my CI onto rc2 the day it dropped. Here is what to look at.

The Python 3.15 changes that matter

The rc2 announcement counts around 144 fixes on top of rc1, so the feature set is settled. The headline items from this cycle:

  • Lazy imports, opt-in, via PEP 810. Imports can defer until first use, which cuts startup cost for large apps that pull in modules they rarely touch.
  • UTF-8 as the default preferred encoding. Opening a file without encoding= no longer quietly follows the locale.
  • A frozendict built-in and a real sentinel type, plus unpacking inside comprehensions.
  • A dedicated profiling package with the Tachyon sampling profiler, and frame pointers on by default.
  • JIT gains reported in the 8 to 13 percent range.

None of these force a rewrite. A couple of them can change behaviour under you, which is the reason to test rather than skim the changelog.

Free-threading and the GIL

This is the slow-motion story worth tracking. The free-threaded build, the one without the global interpreter lock, landed as experimental in 3.13 and became a supported build in 3.14. 3.15 keeps pushing: it adds a stable ABI for free-threaded builds, and the official macOS installer now includes free-threading by default. The free-threading docs track where it stands.

Supported does not mean the default. Your python3.15 still has the GIL. The free-threaded interpreter is python3.15t, a separate build, and the ecosystem is what gates real adoption now, not CPython. A C extension has to declare it is safe to run without the GIL, and plenty still do not. So the practical question for 2026 is not “is the GIL gone”, it is “do my C dependencies work under t yet”.

What to test now

Three things earn a real look before you trust 3.15 in production.

First, run the whole suite on 3.15.0rc2. That is the entire point of a release candidate, and bugs you report now still get fixed before 1 October.

Second, if you ship or depend on C extensions, install the free-threaded build and run under it. A stable ABI means wheels can target it, but “targets it” and “correct under it” are different claims, and data races only show up under load.

Third, grep for open( calls without an encoding= argument. UTF-8 as the default preferred encoding is the change most likely to bite quietly, because code that read a locale-encoded file on someone’s machine will now read it as UTF-8 and may or may not notice. Set the encoding explicitly and the ambiguity goes away.