Oct 13 edition/Reporting & analysis
CodingInfrastructure

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

KEY FACTS
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
Evidence
11 sources across 11 sites
14/100QuietHow 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.

Illustration from Simon Willison’s Weblog: Python 3.15 ships with explicit lazy imports, a built-in sampling profiler and its first measurable JIT speedup
Image: Simon Willison’s Weblog — Original article ↗
THE CORE IDEAS4 TAKEAWAYS
01

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]

02

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]

03

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]

04

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]

WHY IT MATTERS

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

  1. 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 (;).

  2. 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 ().

  3. 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 ().

  4. 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 ().

  5. 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.15 after running uv self update (Willison).
  • Language: lazy import and lazy from ... import (PEP 810), the frozendict built-in (PEP 814), the sentinel built-in (PEP 661), and */`` unpacking inside comprehensions (PEP 798) (What's New).
  • Standard library: a new profiling package (PEP 799). cProfile becomes profiling.tracing, and Tachyon becomes profiling.sampling.
Read the full section
  • Version: CPython 3.15.0, available from python.org or through uv python install 3.15 after running uv self update (Willison).
  • Language: lazy import and lazy from ... import (PEP 810), the frozendict built-in (PEP 814), the sentinel built-in (PEP 661), and */** unpacking inside comprehensions (PEP 798) (What's New).
  • Standard library: a new profiling package (PEP 799). cProfile becomes profiling.tracing, and Tachyon becomes profiling.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.LazyImportType proxy.
  • Tachyon profiler: samples at up to 1 MHz, can attach to a running process by PID, and understands async code.
  • C extensions: the new abi3t stable 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.LazyImportType proxy. The real import happens on first use, and the proxy is then replaced with the actual object. lazy is allowed only at module scope; it cannot be used inside functions, classes or try blocks, 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|none or sys.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 abi3t stable 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=0 restores 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.TaskGroup and timeout(), 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.
FOLLOW THE EVIDENCE

The source trail.

Sources (11)
A LITTLE LESS NOISE. A LOT MORE CONTEXT.

Stay curious.
Follow the evidence.

Independent perspectives, the original sources, and room for the questions that don't have easy answers.

How we build the brief
Connect with us

Find us where you already read.