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:
uv self update
Then, install the latest Python version:
uv python upgrade 3.14
You can start a Python 3.14 REPL with uvx
:
You should upgrade to the latest version of Ruff for Python 3.14 support:
uv tool install ruff@latest
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:
from string.templatelib import Template
name = "World"
f_string: str = f"Hello {name}"
t_string: Template = t"Hello {name}"
This allows consumers of the template to access more information about the definition. For example, you can separate static components and inspect interpolated values:
>>> name = "World"
>>> t_string = t"Hello {name}"
>>> t_string.strings
('Hello ', '')
>>> t_string.values
('World',)
>>> t_string.interpolations
(Interpolation('World', 'name', None, ''),)
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:
$ uvx [email protected]
Downloading cpython-3.14.0+freethreaded-linux-x86_64-gnu (download) (119.0MiB)
Downloading cpython-3.14.0+freethreaded-linux-x86_64-gnu (download)
Python 3.14.0 free-threading build (main, Oct 7 2025, 15:35:12) [Clang 20.1.4 ] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>>
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:
def foo():
try:
1 / 0
except ZeroDivisionError:
print("Caught the exception!")
raise
finally:
return # SyntaxWarning: 'return' in a 'finally' block
foo()
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:
def bar():
try:
1 / 0
except:
return float("inf")
finally:
return 0
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.