CodingSoftware & developer tools
Python 3.15 ships with explicit lazy imports, a built-in sampling profiler and its first measurable JIT speedup
CPython 3.15, released 9 October 2026, adds explicit lazy imports, a built-in sampling profiler and UTF-8 by default. It is the first release where the experimental JIT delivers a measurable speedup. With 3.10 now end of life, libraries can require 3.11.
From the Simon Willison article of October 12, 2026 and cited sources: The release notes report that the experimental JIT is now faster on average: about 7–8% on x86-64 Linux and 11–12% on AArch64 macOS, as geometric means across a benchmark suite. [3] [7] [9]
SOURCES[3] Python Insider: Python 3.15.0 (final) is here! blog.python.org[7] Zeli: Python 3.15's JIT finally beats the standard… zeli.app[9] What's new in Python 3.15 docs.python.org
AI-assisted, not human-edited. Methodology Corrections Who owns this site
- What happened
- The release notes report that the experimental JIT is now faster on average: about 7–8% on x86-64 Linux and 11–12% on AArch64 macOS, as geometric means across a benchmark suite. [3] [7] [9]
- Original source
- Simon Willison article, independent perspective
- Brief by
- AT Pulse research desk AI-assisted; publisher and contact on the desk page
- When
- October 12, 2026 article published
- Covered
- Oct 13 edition
- Evidence
- 11 sources across 11 sites
- 1Hello Python 3.15, goodbye 3.10, and now I can use 3.11simonwillison.net
- 2Shared some notes on Python 3.15, using it with uv, and…x.com
- 3Python Insider: Python 3.15.0 (final) is here!blog.python.org
- 4PEP 810 – Explicit lazy importspeps.python.org
- 5discuss.python.org: PEP 810 threaddiscuss.python.org
- 6LinuxCompatible: 3.10 hits end of lifelinuxcompatible.org
QuietHow it’s measured
Hacker News · 4 likes
Reach blends public engagement (views, likes, comments, shares, stars) from the platforms where the story or its original source lives: YouTube, Hacker News, GitHub, Substack and similar. A video and the article written from its transcript share one score, taken from the video. Platforms with no data are left out rather than counted as zero, and the age of a story never lowers its score.

The release notes report that the experimental JIT is now faster on average: about 7–8% on x86-64 Linux and 11–12% on AArch64 macOS, as geometric means across a benchmark suite. Miguel Grinberg's independent microbenchmarks on a release candidate found 1.20x on Fibonacci and 1.28x on bubble sort. Because they measure different things, the two sets of numbers are not directly comparable. The standard interpreter performed about the same as 3.14. [3] [7] [9]
PEP 810 adds opt-in `lazy import` syntax. It binds a name to a proxy and only does the real import when the name is first used. This lets CLI tools and plugin hosts that load heavy dependencies cut startup time. The trade-off is that import errors show up at first use rather than at the import line. The proposal follows the rejection of PEP 690, which would have made all imports lazy implicitly. [4] [5] [9] [1]
A new standard-library `profiling` package includes Tachyon, a sampling profiler. It can attach to a running process by PID, handles async code, and outputs flame graphs and other formats. Frame pointers are now on by default, and UTF-8 is the default encoding. Setting `PYTHONUTF8=0` brings back the old locale-dependent behaviour. [9] [1]
Python 3.10 reached end of life with 3.10.22 on 1 October. Projects that support every maintained version can now set 3.11 as their minimum. That makes features such as `tomllib`, `asyncio.TaskGroup` and newer SQLite functions available everywhere they run. Simon Willison has made this change in his projects, including dropping a SQLite workaround in Datasette. [6] [1]
Lazy imports and an attachable profiler have shipped as working features. The JIT gains so far are modest averages from benchmarks.
Read the full assessment
In practice, CLI tools with heavy ML dependencies can cut startup time, and systems still on 3.10 no longer receive security patches.
Executive brief
Python 3.15 shipped on 9 October 2026. On the official release notes' account, it is the first release where the experimental JIT gives a clear speedup: 7–8% geometric mean on x86-64 Linux and 11–12% on AArch64 macOS. Microbenchmarks by Miguel Grinberg point the same way. The changes most likely to affect day-to-day work are explicit lazy import statements, a sampling profiler in the standard library, and UTF-8 as the default encoding. Python 3.10 reached end of life on 1 October, so projects that support every maintained version can now require 3.11 as a minimum, as Simon Willison is doing.
What changed and event timeline
Lazy imports accepted
The Steering Council unanimously accepted PEP 810 for Python 3.15. It replaces the implicit, global approach of PEP 690, which had been rejected, with explicit opt-in syntax (;).
Python 3.10 reaches end of life
Python 3.10.22 was the final release of the series. Updates to 3.11 through 3.14 shipped the same day. Release manager Pablo Galindo Salgado urged users to upgrade ().
Independent JIT benchmark
Testing 3.15.0rc3, Grinberg found the standard interpreter only slightly faster than 3.14. The JIT build was 1.20x faster on Fibonacci and 1.28x on bubble sort ().
Python 3.15.0 final
The release includes 5,643 commits from 1,012 contributors. Its release managers are Hugo van Kemenade, Ned Deily and Steve Dower ().
Practitioner migration notes
Willison documents upgrading through uv, raises the minimum Python version for his projects to 3.11, and removes a SQLite workaround from Datasette ().
Capabilities and access
- Version: CPython 3.15.0, available from python.org or through
uv python install 3.15after runninguv self update(Willison). - Language:
lazy importandlazy from ... import(PEP 810), thefrozendictbuilt-in (PEP 814), thesentinelbuilt-in (PEP 661), and*/`` unpacking inside comprehensions (PEP 798) (What's New). - Standard library: a new
profilingpackage (PEP 799).cProfilebecomesprofiling.tracing, and Tachyon becomesprofiling.sampling.
Read the full section
- Version: CPython 3.15.0, available from python.org or through
uv python install 3.15after runninguv self update(Willison). - Language:
lazy importandlazy from ... import(PEP 810), thefrozendictbuilt-in (PEP 814), thesentinelbuilt-in (PEP 661), and*/**unpacking inside comprehensions (PEP 798) (What's New). - Standard library: a new
profilingpackage (PEP 799).cProfilebecomesprofiling.tracing, and Tachyon becomesprofiling.sampling. - Platforms: Windows 64-bit binaries use the tail-calling interpreter, and macOS installers include free-threading builds (release notes).
Technical analysis for researchers and developers
- How lazy imports work: a lazy import binds the name to a
types.LazyImportTypeproxy. - Tachyon profiler: samples at up to 1 MHz, can attach to a running process by PID, and understands async code.
- C extensions: the new
abi3tstable ABI (PEP 803) lets a single extension build target free-threaded CPython.
Read the full section
- How lazy imports work: a lazy import binds the name to a
types.LazyImportTypeproxy. The real import happens on first use, and the proxy is then replaced with the actual object.lazyis allowed only at module scope; it cannot be used inside functions, classes ortryblocks, or with star imports. Import errors appear when the name is first used rather than at the import line. Behaviour can be controlled globally with-X lazy_imports=normal|all|noneorsys.set_lazy_imports_filter(). Code that must also run on older versions can declare lazy modules through__lazy_modules__(PEP 810). - Tachyon profiler: samples at up to 1 MHz, can attach to a running process by PID, and understands async code. It outputs flame graphs, heat maps, collapsed stacks, Firefox Profiler format and a live terminal view. Frame pointers are now enabled by default (PEP 831), which helps external profilers (What's New).
- C extensions: the new
abi3tstable ABI (PEP 803) lets a single extension build target free-threaded CPython.
Claims and evidence
- JIT speedup: the official figures (7–8% and 11–12%) are geometric means on a benchmark suite. Grinberg's 1.20x and 1.28x results come from two microbenchmarks only (summary).
- Standard interpreter vs 3.14: Grinberg found it roughly flat (Willison). The free-threaded build performed about the same as it did in 3.14 (summary).
- Lazy import cost: PEP 810 claims that once a name has been resolved there is zero ongoing overhead.
Read the full section
- JIT speedup: the official figures (7–8% and 11–12%) are geometric means on a benchmark suite. Grinberg's 1.20x and 1.28x results come from two microbenchmarks only (summary). The two sets of numbers measure different things and should not be compared directly. Grinberg himself cautions that no single objective measure of language performance exists.
- Standard interpreter vs 3.14: Grinberg found it roughly flat (Willison). The free-threaded build performed about the same as it did in 3.14 (summary).
- Lazy import cost: PEP 810 claims that once a name has been resolved there is zero ongoing overhead. This is the authors' claim; no independent benchmark of it appears in the reviewed sources (PEP 810).
Context and prior work
- PEP 690 proposed implicit lazy imports for all modules and was rejected. PEP 810 deliberately makes laziness explicit and local to each import (PEP 810).
- PEP 798 extends the unpacking syntax that PEP 448 introduced in Python 3.5 in 2015 (Willison).
- For 3.14, Grinberg had measured large gains over 3.13, roughly 27% on fib(40) (Grinberg 3.14).
Read the full section
- PEP 690 proposed implicit lazy imports for all modules and was rejected. PEP 810 deliberately makes laziness explicit and local to each import (PEP 810).
- PEP 798 extends the unpacking syntax that PEP 448 introduced in Python 3.5 in 2015 (Willison).
- For 3.14, Grinberg had measured large gains over 3.13, roughly 27% on fib(40) (Grinberg 3.14). That makes 3.15's flat standard interpreter a change from the previous release's pattern.
- External sampling profilers such as py-spy were the usual way to do this kind of profiling before Tachyon.
Limitations, safety and contested findings
- EOL wording: Willison ties 3.10's end of support to the 3.15 launch, but support actually ended with 3.10.22 on 1 October (LinuxCompatible).
- JIT status: the JIT is still labelled experimental (What's New).
- Error timing: with lazy imports, a failing import can raise an error well after the import line, far from where it is written (PEP 810).
Read the full section
- EOL wording: Willison ties 3.10's end of support to the 3.15 launch, but support actually ended with 3.10.22 on 1 October (LinuxCompatible). Some vendor guides cite 31 October instead (HeroDevs).
- JIT status: the JIT is still labelled experimental (What's New).
- Error timing: with lazy imports, a failing import can raise an error well after the import line, far from where it is written (PEP 810).
- UTF-8 default: code that relied on locale-dependent encodings may behave differently. Setting
PYTHONUTF8=0restores the old behaviour. - macOS 27.0: IDLE and tkinter dialogs may hang, and this affects every current Python version (release notes).
- Profiling permissions: attaching Tachyon to a process on macOS required
sudo(Willison).
Business and practitioner implications
- Startup time: CLI tools and plugin hosts that load heavy machine-learning dependencies can replace manual workarounds with
lazy import. - Production profiling: being able to attach a profiler to a running process removes the need to install third-party profilers.
- Upgrade urgency: fleets still on 3.10 are now running without security patches.
Read the full section
- Startup time: CLI tools and plugin hosts that load heavy machine-learning dependencies can replace manual workarounds with
lazy import. Willison cites multi-second startup costs in his LLM CLI's plugin system (Willison). - Production profiling: being able to attach a profiler to a running process removes the need to install third-party profilers.
- Upgrade urgency: fleets still on 3.10 are now running without security patches.
- Using 3.11 features: libraries can now depend on
tomllib,asyncio.TaskGroupandtimeout(),datetime.UTC, and the 3.11 SQLite additions (blobopen, window functions, runtime limits). - Performance testing: test the JIT on real workloads before planning capacity around it.
The source trail.
Sources (11)
Hello Python 3.15, goodbye 3.10, and now I can use 3.11
Article text retrieved; extracted text may omit tables or interactive elements.
simonwillison.netShared some notes on Python 3.15, using it with uv, and features from Python 3.11 I'm excited to use now that 3.10 is no longer the minimum supported version for my own p
Related coverage; assess separately
x.com