๐ Python 3.14: t-Strings Look Like f-Strings, But They Aren’t Strings
An f-string takes your variables and glues them into a string immediately. That’s lovely for greetings and terrible for SQL, HTML and shell commands, where “just glue it” is how injection bugs are born.
Python 3.14, released on 7 October 2025, adds a sibling: the template string.
The discovery: Same syntax, different result
A t-string uses a t prefix instead of f. Unlike an f-string, it doesn’t return a str. It returns an object that keeps the static and interpolated parts separate:
Iterating over a Template gives you plain strings for the static text and Interpolation objects for the {...} parts. That output comes straight from the “What’s new in Python 3.14” page, which describes the feature in PEP 750.
A concrete example
Because the code that renders the result can tell trusted text from interpolated values, it can treat them differently. Here’s a small HTML renderer that escapes only the interpolated parts:
from html import escape
from string.templatelib import Interpolation
defsafe_html(template):
parts = []
for part in template:
if isinstance(part, Interpolation):
parts.append(escape(str(part.value)))
else:
parts.append(part)
return"".join(parts)
name ='<script>alert("hi")</script>'print(safe_html(t"<p>Hello, {name}</p>"))
# <p>Hello, <script>alert("hi")</script></p>
The Python documentation suggests the same idea for sanitising user input, and mentions SQL, shell operations, logging and HTML as candidates.
The important nuance: The template does nothing by itself
A t-string is not a safer f-string. It’s the raw material. All the safety comes from the function you pass it to:
A Template is not a str, so existing APIs that expect strings won’t understand it. Libraries have to add explicit support for Template.
My example ignores the interpolation’s conversion and format spec for brevity. A real renderer should decide what to do with them.
Escaping depends on context. Text that’s safe inside an HTML element isn’t automatically safe inside an attribute or a script block.
This feature requires Python 3.14 or later.
The takeaway โ
Use f-strings for text you’re about to display. Reach for t-strings when a library or your own function needs to treat interpolated values differently from the surrounding text.
Same curly braces, very different responsibilities.