![]() |
With Python 3.14 comes an important new feature: t-string, a new syntax similar to f-strings, but designed to improve security when composing texts that include variables, such as SQL queries, HTML, external commands, etc.
F-strings are perfect for immediate formatting:
name = "Alice"
print(f"Hello {name}")
But when the content comes from outside (user input, database, API...), inserting it directly into the text can be dangerous (injection).
T-strings are used for precisely this: keeping text and values, so libraries can treat inputs as safe data.
🔍 What's the difference between f-string and t-string?
✔ f-string
- They produce a string immediately (
str) - They interpolate variables directly
- They do not protect against injection
✔ t-string
- They produce a Template object, not a string
- separate:
- static text parts (
strings) - interpolation points (
interpolations) - do not interpolate themselves
- allow libraries to safely replace values (e.g., escaping, parameterization, sanitization)
🧠 A simple example: from f-string to t-string
🔵 f-string (immediate result)
name = "Alice"
print(f"Hello {name}")
Hello Alice🟢 t-string (same purpose, but safer)
name = "Alice"
tmpl = t"Hello {name}"
But here's something important: tmpl is not a string!
It's a Template.
To see what it looks like:
print(tmpl.strings) # ['Hello ', '']
print(tmpl.interpolations) # ['name']
This shows the structure of the template:
- first part of text:
"Hello " - interpolation point:
name - final part (empty)
So… how do I get the string "Hello Alice"?
It depends on the context in which the template is used.
Python doesn't provide a .render() method: this is intentional. It's up to the libraries (databases, HTML, sanitizers, etc.) to decide how to safely replace values.
For example, a SQL library could use the template to generate a parameterized query:
query = t"SELECT * FROM users WHERE name = {name}"
db.execute(query, name=name) # the library will apply safe interpolation
🔐 Why do t-strings improve security?
Because they prevent inserted values from being treated as code.
With an f-string, the content is inserted into the string:
f"SELECT * FROM users WHERE name = '{name}'"
With a t-string, however, the library sees:
- fixed part:
SELECT * FROM users WHERE name = - parameter:
name
And you can decide to:
- perform escaping
- use parameterized queries
- reject suspicious values
- log the variable part separately
In practice, the t-string makes an injection attack difficult or impossible, because the user value is never merged into the text.
📝 Summary
| Purpose | f-string | t-string |
|---|---|---|
| Quick Format | ✔️ | ➖ is not the purpose |
| Produce a string immediately | ✔️ | ❌ |
| Separate data from text | ❌ | ✔️ |
| Injection-safe | ❌ | ✔️ |
| Used in SQL, HTML, JSON, API | ❌ risky | ✔️ ideal |
🎯 Conclusion
If you want to print something or format plain text:
print(f"Hello {name}")
If you're passing content to external systems (databases, shell commands, APIs, etc.):
tmpl = t"Hello {name}"
You don't generate the final result:
The library using the template will safely replace the values, preventing injection.
And remember: Template instances are not strings 😉
More information
- Python's new t-strings — https://davepeck.org/2025/04/11/pythons-new-t-strings/
Follow me #techelopment
Official site: www.techelopment.it
facebook: Techelopment
instagram: @techelopment
X: techelopment
Bluesky: @techelopment
telegram: @techelopment_channel
whatsapp: Techelopment
youtube: @techelopment
