Python 3.14, the next stable version of Python, is available now, along with new versions of Ruff and uv!
First, upgrade to the latest version of uv:
Then, install the latest Python version:
You can start a Python 3.14 REPL with uvx:
You should upgrade to the latest version of Ruff for Python 3.14 support:
There are a lot of exciting new features in Python 3.14 — we've picked a few major ones to talk about.
Template strings #
Template strings (t-strings) build upon the established f-string syntax to offer another means of interpolating values into strings. Unlike f-strings, which evaluate to a regular str at runtime, t-strings evaluate to the new string.templatelib.Template type:
This allows consumers of the template to access more information about the definition. For example, you can separate static components and inspect interpolated values:
PEP 750, which proposed the addition of t-strings to the language, contains some realistic applications like implementing f-strings via t-strings, structured logging, and HTML templating.
All of the Ruff rules for strings have been updated to accommodate t-strings, including rules like PLE2510-PLE2515, which detect invalid characters in strings, and the ISC rules, which deal with implicit string concatenation.
Ruff will emit a new syntax error if a t-string is implicitly concatenated to another string type. t-strings can be concatenated to other t-strings, either implicitly or explicitly (with the + operator), but they cannot be mixed with other string or byte literals.
Free-threaded Python #
As of Python 3.14, the free-threaded (or no-GIL) version of the Python interpreter is no longer considered experimental.
The global interpreter lock (GIL) limits multi-threaded concurrency in exchange for simplified safety guarantees. Consequently, CPU-bound Python code needs to use multi-processing or subinterpreters for performant concurrency, but these techniques have downsides, e.g., it's harder to share objects across workers.
It's been a long-standing goal to enable ergonomic performance improvements by bypassing the GIL. However, multiple previous attempts have been waylaid by concerns about regressions in single-threaded performance and the complexity of rolling out the change in an ecosystem built around implicit multi-threaded safety.
PEP 703 introduced a separate, optional build configuration for CPython with the GIL disabled in early 2023, initiating phase one of a three-phase stabilization plan announced by the steering council. Following the success of the experimental first phase of work on the free-threaded build in the Python 3.13 and 3.14 development cycles, PEP 779 was accepted for Python 3.14, moving the project to phase two. This phase entails full, official support, but still maintains the optional status of the build. The steering council additionally outlined the criteria for moving to phase three, where the free-threaded build would become the default.
Try out the free-threaded build of Python with uv by appending a t to the Python version:
There are a few limitations in the current version, including single-threaded performance degradation and memory usage increases (on the order of 10%).
uv required explicit opt-in to use discovered Python 3.13 free-threaded interpreters. Now, uv will allow using Python 3.14+ free-threaded interpreters in virtual environments or on the PATH without additional opt-in. This does not apply to installing Python, in which the normal build remains the default.
Give the free-threaded builds a try and report any issues you run into, especially for multi-threaded workflows, where performance should be improved!
A performance boost for interpreters built with Clang #
Python 3.14 comes with a new type of interpreter which uses a tail call-based implementation to improve performance. Benchmarks suggest a 3-5% improvement on the pyperformance benchmark suite.
The new interpreter is currently only supported when building Python with Clang 19+, which happens to be the compiler we're using for our distributions of Python in python-build-standalone. This means that uv users on common architectures should see an additional performance boost when using managed versions of Python 3.14.
New syntax warnings in finally clauses #
The usage of return, break, or continue in the finally clause of a try-except statement now causes a SyntaxWarning to be emitted:
Using one of these control-flow statements in the finally clause prevents exceptions that appear to be re-raised in the except clauses from actually being re-raised. The above example exits successfully after printing Caught the exception!. return statements in except clauses will also be swallowed by any of these control-flow statements in a finally block:
bar here returns 0 instead of inf from the except clause.
Ruff already had a rule to catch cases like this, jump-statement-in-finally (B012), but it is not currently enabled by default. You may want to consider enabling it in your projects, both because it can detect surprising behaviors on any version of Python, and to avoid encountering warnings on Python 3.14+.
For more details, see PEP 765.
typing.ByteString has been deprecated (again) #
Both typing.ByteString and collections.abc.ByteString have been deprecated since Python 3.9 and were slated for removal in 3.14. However, the deprecation warnings weren't prominent enough to reduce their usage significantly across the ecosystem, and removal of the types has been delayed to Python 3.17.
As noted in the documentation, the reason for the deprecation is that ByteString was originally intended to be an abstract base class (ABC), but it never had any methods and thus wasn't very useful. Since Python 3.12, the more useful collections.abc.Buffer ABC has been in the standard library and should be preferred. On earlier versions of Python, the typing_extensions.Buffer backport can be used instead, or a simple union of types like bytes | bytearray | memoryview.
Like B012 above, Ruff already has a rule that flags both import and use of the ByteString type, the aptly-named byte-string-usage (PYI057) rule. PYI057 is also not enabled by default, but you may want to enable it now to prepare for the eventual removal of the ByteString type.
REPL improvements #
We love the Python REPL! It's a great way to test out Python semantics when working on our tooling. We're excited that Python 3.14 extends the excellent improvements to the REPL in Python 3.13 with new syntax highlighting and import autocompletion.
The screencast below shows off these features, along with some more changes in 3.14, like the new functools.Placeholder and concurrent.futures.InterpreterPoolExecutor APIs.
Screencast of new REPL features in Python 3.14
Python 3.9 is reaching end of life #
The release of Python 3.14 coincides closely with the end of the five-year support window for Python 3.9, which was first released on October 5, 2020. Following a final release this month, Python 3.9 will no longer receieve security updates.
As a result, Ruff v0.14 also increases the default Python version from 3.9 to 3.10. This default only applies if no target-version or requires-python version is specified in your Ruff or pyproject.toml configuration, respectively. This also does not affect the minimum supported Python version in Ruff, which remains at Python 3.7.
uv will continue to support Python 3.9. However, additional builds (e.g., with security fixes for dependencies) after the final release of Python 3.9 will not be published.
What else is changing? #
If you want to know more, you can find an extensive list of the changes to Python in the "What's new in Python 3.14" page. You can also check out the full changelogs for Ruff and uv on GitHub.
Thank you! #
Thank you to the CPython team for improving Python and to everyone who provided feedback on the Python 3.14 pre-releases and preview support in Ruff and uv.
Read more about Astral — the company behind these tools.
Thanks to Zanie Blue, Zsolt Dollenstein, David Peter, Micha Reiser, Geoffrey Thomas, and Alex Waygood who contributed to this blog post.