Dev News Daily ENDE

Python 3.15.0: lazy imports, frozendict, UTF-8 by default, and a macOS 27 warning

Python 3.15.0 was released on 9 October 2026 — 5,643 commits from 1,012 contributors since 3.14, according to the release page. The headline list is long; four items change how ordinary code behaves, and one is a warning that belongs at the top of any upgrade ticket.

Lazy imports (PEP 810). A new soft keyword, lazy, marks an import whose module is only loaded when the name is first touched: lazy import heavy_module binds a lightweight proxy at import time. If loading later fails, the exception is raised at the point of first use, and the traceback shows both that point and the original import line. It is allowed only at module scope — inside a function, class body or try block it is a SyntaxError, and star or __future__ imports cannot be lazy. Projects can switch it on globally with -X lazy_imports or PYTHON_LAZY_IMPORTS, and narrow it with sys.set_lazy_imports_filter() — for example, lazy for your own modules, eager for third-party ones.

frozendict (PEP 814). An immutable mapping is now a builtin. It is not a subclass of dict, so isinstance(x, dict) checks will reject it; the What's New text suggests (dict, frozendict) or collections.abc.Mapping instead. It keeps insertion order but compares without regard to order, and is hashable when its contents are.

UTF-8 is the default encoding (PEP 686). open('file.txt') without an encoding argument now reads and writes UTF-8 regardless of the system locale. On Linux and macOS that is mostly what already happened; on Windows machines with a legacy code page it is a behaviour change for every file opened without an explicit encoding. The escape hatch is -X utf8=0, and encoding='locale' (available since 3.10) asks for the old behaviour explicitly.

Python 3.15.0: lazy imports, frozendict, UTF-8 by default, and a macOS 27 warning
Python 3.15.0: lazy imports, frozendict, UTF-8 by default, and a macOS 27 warning — Dev News Daily

A profiling package (PEP 799). profiling.tracing holds the deterministic profiler formerly known as cProfile (the old name stays as an alias), and profiling.sampling is Tachyon, a new high-frequency statistical sampling profiler. The pure-Python profile module is deprecated for removal in 3.17. Frame pointers are now on by default (PEP 831), which the release page presents as improved system-level observability.

Also listed: a stable ABI for free-threaded builds (PEPs 803, 820, 793), macOS installers that install free-threading support by default, Windows 64-bit binaries built with the tail-calling interpreter, and an experimental JIT the release page credits with a 7–8% geometric-mean gain on x86-64 Linux and 11–12% on AArch64 macOS over the respective baseline interpreters.

The warning. On macOS 27.0, Tk-based applications — IDLE and anything using tkinter — may hang when a menu command opens a dialog, ending in a spinning cursor and Force Quit. The release page attributes it to an operating-system behaviour change that is believed to affect every current Tk version, and therefore tkinter in all current Python versions, not just 3.15. Users who depend on Tk apps are told to hold off on macOS 27.0 or test their workflow first; the tracking issue is CPython #158053.

Sources: Python.org, Python 3.15.0 release page — https://www.python.org/downloads/release/python-3150/ ; What's new in Python 3.15 — https://docs.python.org/3/whatsnew/3.15.html

Written by Victoria Shinder.