The new t-strings ease the creation of strings meant to represent other languages, embedded in a Python program, while preserving information about the variables and expressions interpolated so that specialized glue/connection code to that other language can do things like syntax checking, character escaping, security auditing, and in general adding specific punctuation to those interpolated values. The full proposal is in PEP 750.

The important thing to have in mind is that a t-string by itself adds no value. Just when combined with a call to a consumer of that string, which might be a SQL connector, an HTML renderer, or even a regular expression template, the extra information - when compared with an f-string - present in the t-string will add value.

In other words, while an f-string is immediately rendered into an immutable, plain str instance when found, a t-string is converted into a Template object which preserves information about the individual interpolated values (and if needed, their original expressions). This template instance is then passed to a call which will act on the string, special casing these values. For example, a t-string aware SQL connector can automatically escape in a safe way all interpolated values, mitigating any possible SQL injection vulnerability.

For a simple usage example not in the docs, here is a simple interactive mode snippet which will wrap the templated values in a CSI ANSI code sequence to change the terminal color. I set up constant values with the color codes I am using for the example:


In [26]: from string import templatelib

In [27]: red = 31; reset=0; green = 32

In [28]: a = t"The next {red}text{reset} should be {green}in another color{reset}"

In [29]: for part in a:
    ...:     if isinstance(part, templatelib.Interpolation):
    ...:         part = f"\x1b[{part.value}m"
    ...:     # else: -> implies 'part' is a regular str object
    ...:     print(part, end="")
    ...: 

This prints some text colored according to the example in a functional terminal (not windows CMD).

Still in this summary, it is worth noting that t-strings, like f-strings are eagerly evaluated. This means the values for the variables in the interpolated expressions are used as they are when the line of code where the t-string is expressed is executed: even if the variable changes later on, the orignal value is saved in the template object. The converse behavior, having the values dynamically change with the values assigned to the variables in the expressions was reasoned out in the discussions leading to the feature. (check the rejected ideas session in PEP 750)

Answer from jsbueno on Stack Overflow
Top answer
1 of 2
21

The new t-strings ease the creation of strings meant to represent other languages, embedded in a Python program, while preserving information about the variables and expressions interpolated so that specialized glue/connection code to that other language can do things like syntax checking, character escaping, security auditing, and in general adding specific punctuation to those interpolated values. The full proposal is in PEP 750.

The important thing to have in mind is that a t-string by itself adds no value. Just when combined with a call to a consumer of that string, which might be a SQL connector, an HTML renderer, or even a regular expression template, the extra information - when compared with an f-string - present in the t-string will add value.

In other words, while an f-string is immediately rendered into an immutable, plain str instance when found, a t-string is converted into a Template object which preserves information about the individual interpolated values (and if needed, their original expressions). This template instance is then passed to a call which will act on the string, special casing these values. For example, a t-string aware SQL connector can automatically escape in a safe way all interpolated values, mitigating any possible SQL injection vulnerability.

For a simple usage example not in the docs, here is a simple interactive mode snippet which will wrap the templated values in a CSI ANSI code sequence to change the terminal color. I set up constant values with the color codes I am using for the example:


In [26]: from string import templatelib

In [27]: red = 31; reset=0; green = 32

In [28]: a = t"The next {red}text{reset} should be {green}in another color{reset}"

In [29]: for part in a:
    ...:     if isinstance(part, templatelib.Interpolation):
    ...:         part = f"\x1b[{part.value}m"
    ...:     # else: -> implies 'part' is a regular str object
    ...:     print(part, end="")
    ...: 

This prints some text colored according to the example in a functional terminal (not windows CMD).

Still in this summary, it is worth noting that t-strings, like f-strings are eagerly evaluated. This means the values for the variables in the interpolated expressions are used as they are when the line of code where the t-string is expressed is executed: even if the variable changes later on, the orignal value is saved in the template object. The converse behavior, having the values dynamically change with the values assigned to the variables in the expressions was reasoned out in the discussions leading to the feature. (check the rejected ideas session in PEP 750)

2 of 2
2

The What's New page has various examples, and some potential applications of template strings.

With this in place, developers can write template systems to sanitize SQL, make safe shell operations, improve logging, tackle modern ideas in web development (HTML, CSS, and so on), and implement lightweight, custom business DSLs.

from string.templatelib import Template, Interpolation

def lower_upper(template: Template) -> str:
    """Render static parts lowercased and interpolations uppercased."""
    parts: list[str] = []
    for item in template:
        if isinstance(item, Interpolation):
            parts.append(str(item.value).upper())
        else:
            parts.append(item.lower())
    return "".join(parts)

name = "world"
assert lower_upper(t"HELLO {name}") == "hello WORLD"

The main difference is the following:

Compared to using an f-string, the html function has access to template attributes containing the original information: static strings, interpolations, and values from the original scope.

🌐
Real Python
realpython.com › python-t-strings
Python 3.14: Template Strings (T-Strings) – Real Python
July 2, 2025 - They’re also valuable in other fields that rely on string templates, such as structured logging. By the end of this tutorial, you’ll understand that: Python t-strings are a generalization of f-strings, designed to safely handle and process ...
Discussions

Template strings in Python 3.14: an useful new feature or just an extra syntax?
This seems useful to formalize what templating systems already do. More on reddit.com
🌐 r/Python
98
167
May 1, 2025
T-Strings: Python's Fifth String Formatting Technique?
There should be one, and preferably only one obvious way to do something. Unless it's string formatting. Then you need ten. More on reddit.com
🌐 r/Python
74
228
October 21, 2025
Python’s new t-strings
db.execute("QUERY WHERE name = ?", (name,)) with · db.execute(t"QUERY WHERE name = {name}") Does the benefit from this syntactic sugar outweigh the added complexity of a new language feature? I think it does in this case for two reasons: More on news.ycombinator.com
🌐 news.ycombinator.com
466
620
May 1, 2025
is there any difference between using string.format() or an fstring?
Don't forget that f-strings haven't been around forever. It may be partly old habits, it may be not keeping up to date with features, they may still be wanting to target a minimum python version that didn't support f-strings. I'd tend to prefer to use f-strings, but I wouldn't crucify someone for using perfectly valid language constructs. More on reddit.com
🌐 r/Python
145
317
October 9, 2022
🌐
Python Morsels
pythonmorsels.com › t-strings-in-python
T-strings: Python's Fifth String Formatting Technique? - Python Morsels
October 20, 2025 - T-strings are for lazy string interpolation. Python's f-strings immediately interpolate the expressions within their replacement fields (the bit between the curly braces).
🌐
Medium
medium.com › @Manoj-Bharathi-S › pythons-f-strings-vs-t-strings-a-deep-dive-into-safety-and-power-87bf1810e6ae
Python’s F-Strings vs. T-Strings: A Deep Dive into Safety and Power | by Manoj Bharathi | Medium
September 17, 2025 - T-strings offer a modern solution that combines the clean syntax of f-strings with a powerful new safety mechanism. Unlike f-strings, which immediately produce a plain string, t-strings resolve to a special Template object.
🌐
Davepeck
davepeck.org › 2025 › 04 › 11 › pythons-new-t-strings
Python's new t-strings | Dave Peck
April 11, 2025 - It’s a fancy way of saying “this part of your string was created by substitution.” · By giving developers access to the parts of strings, t-strings make it possible to write code that processes strings in powerful and safe ways. Since they were introduced in Python 3.6, f-strings have ...
🌐
Hacker News
news.ycombinator.com › item
Building off this question, it's not clear to me why Python should have both t-s... | Hacker News
April 21, 2025 - My main motivation as an author of 501 was to ensure user input is properly escaped when inserting into sql, which you cant enforce with f-strings · I used to wish for that and got it in JS with template strings and libs around it. For what it’s worth (you got a whole PEP done, you have ...
🌐
Reddit
reddit.com › r/python › template strings in python 3.14: an useful new feature or just an extra syntax?
r/Python on Reddit: Template strings in Python 3.14: an useful new feature or just an extra syntax?
May 1, 2025 -

Python foundation just accepted PEP 750 for template strings, or called t-strings. It will come with Python 3.14.

There are already so many methods for string formatting in Python, why another one??

Here is an article to dicsuss its usefulness and motivation. What's your view?

Find elsewhere
🌐
Python
peps.python.org › pep-0750
PEP 750 – Template Strings - Python Enhancement Proposals
July 8, 2024 - Work on this PEP was resumed by a different author in March 2023, introducing “t-strings” as template literal strings, and built atop PEP 701. The authors of this PEP consider it to be a generalization and simplification of the updated work in PEP 501. (That PEP has also recently been updated to reflect the new ideas in this PEP.) Python f-strings are easy to use and very popular.
🌐
YouTube
youtube.com › watch
Why t-string over f-string? 2MinutesPy - YouTube
Python already gave us powerful f-strings… so why introduce t-strings?In this video, I break down the reason behind t-strings and why they solve a problem th...
Published   December 9, 2025
🌐
InfoWorld
infoworld.com › home › software development › programming languages › python
How to use template strings in Python 3.14 | InfoWorld
September 26, 2025 - It’s hard, if not impossible, to do things like inspect each variable as it’s inserted into the string and take some action based on what it is. Python 3.14 has a new feature called the template string, or t-string, type. A t-string superficially resembles an f-string, but it’s designed to do something very different.
🌐
Medium
medium.com › @ajaymaurya73130 › template-string-in-python-3-14-vs-f-strings-which-one-should-you-use-a31fbcb3924b
Template String in Python 3.14 vs F-Strings: Which One Should You Use? | by Ajaymaurya | Medium
July 20, 2025 - Unlike f-strings, which execute Python expressions directly within the string, T-strings focus on security, readability, and reusability — especially useful when rendering templates or integrating user data.
🌐
Reddit
reddit.com › r/python › t-strings: python's fifth string formatting technique?
r/Python on Reddit: T-Strings: Python's Fifth String Formatting Technique?
October 21, 2025 -

Every time I've talked about Python 3.14's new t-strings online, many folks have been confused about how t-strings are different from f-strings, why t-strings are useful, and whether t-strings are a replacement for f-strings.

I published a short article (and video) on Python 3.14's new t-strings that's meant to explain this.

The TL;DR:

  • Python has had 4 string formatting approaches before t-strings

  • T-strings are different because they don't actually return strings

  • T-strings are useful for library authors who need the disassembled parts of a string interpolation for the purpose of pre-processing interpolations

  • T-strings definitely do not replace f-strings: keep using f-strings until specific libraries tell you to use a t-string with one or more of their utilities

Watch the video or read the article for a short demo and a library that uses them as well.

If you've been confusing about t-strings, I hope this explanation helps.

🌐
Talk Python To Me
talkpython.fm › episodes › show › 505 › t-strings-in-python-pep-750
Episode #505 - t-strings in Python (PEP 750) | Talk Python To Me Podcast
May 13, 2025 - Python has many string formatting styles which have been added to the language over the years. Early Python used the % operator to injected formatted values into strings. And we have string.format() which offers several powerful styles. Both were verbose and indirect, so f-strings were added in Python 3.6. But these f-strings lacked security features (think little bobby tables) and they manifested as fully-formed strings to runtime code.
🌐
Lobsters
lobste.rs › s › p5g7rn › python_s_new_t_strings
Python's new t-strings | Lobsters
April 21, 2025 - AFAIK it’s not possible to do something like this with f-strings, which feel more like a parse-time construct than a run-time one. As far as the % operator… when I was writing Python professionally ~5 years ago, there seemed to be consensus that the format method should always be used instead.
🌐
Snarky
snarky.ca › unravelling-t-strings
Unravelling t-strings
May 16, 2025 - We parsed f"Hello, {name}! Conversions like {name!r} and format specs like {name:<6} work!" into Template("Hello, ", Interpolation(name, "name"), "! Conversions like ", Interpolation(name, "name", "r"), " and format specs like ", Interpolation(name, "name", format_spec="<6")," work!"). We were then able to use our f_yeah() function to convert the t-string into what an equivalent f-string would have looked like. The actual code to use to test this in Python 3.14 with an actual t-string is the following (PEP 750 has its own version of converting a t-string to an f-string which greatly inspired my example):
🌐
Medium
medium.com › @DahlitzF › pythons-f-strings-vs-str-e22995cefef6
Python’s f-strings vs. str()
December 26, 2018 - To summarize f-strings are faster than str() in terms of converting integers and such types to string. But keep in mind, that we only had a look at simple types. How they perform on more complex types is currently out of my knowledge as I didn’t test it. Feel free to leave a comment with your own thoughts. Stay curious and keep coding! ... Student, Developer, IBMer. Member of the RealPython.com team. Coding and sports are my passion. Python | C/C++ | Java
🌐
Real Python
realpython.com › python-f-strings
Python's F-String for String Interpolation and Formatting – Real Python
November 30, 2024 - By the end of this tutorial, you’ll understand that: An f-string in Python is a string literal prefixed with f or F, allowing for the embedding of expressions within curly braces {}.
🌐
Hacker News
news.ycombinator.com › item
Python’s new t-strings | Hacker News
May 1, 2025 - db.execute("QUERY WHERE name = ?", (name,)) with · db.execute(t"QUERY WHERE name = {name}") Does the benefit from this syntactic sugar outweigh the added complexity of a new language feature? I think it does in this case for two reasons: