Python Just Got a New Kind of String. It Could End a Whole Class of Security Bugs.
t-strings (PEP 750) are the biggest change to Python string formatting since f-strings, and they exist for one reason: f-strings cannot be made safe. Here is what they are and why they matter. Every SQL injection, every cross-site scripting hole, every shell-injection bug has the same shape at its heart. Somebody took a piece of untrusted input and glued it directly into a string that was then treated as code, as a query, as markup. The input became structure instead of data. query = f"SELECT * FROM users WHERE name = '{name}'" If name is O'Brien, the apostrophe closes the quoted value early and the query breaks. If name is crafted by an attacker, the same mechanism lets them add their own commands to your query. The f-string did exactly what it was designed to do: take the value and put it in the string. Immediately. Finished. And that immediacy is precisely the problem. By the time you have the string, the dangerous value is already welded into it, indistinguishable from the safe parts. There is no seam left to escape. Python 3.14 introduced a new kind of string literal, standardized in PEP 750, built specifically to fix this. They are called t-strings (template strings), and as the Python 3.15 world settles in late 2026, they are the most consequential change to string handling since f-strings arrived. Here is what they are, how they differ from f-strings in one crucial way, and why that difference can close an entire category of vulnerabilities. The One Difference That Changes Everything A t-string looks almost exactly like an f-string. Same braces, same interpolation syntax. The only visible change is the prefix: t instead of f. name = "Pythonista" greeting = t"Hello, {name}!" But the result is completely different in the way that matters. An f-string evaluates to a finished str. A t-string evaluates to a Template object, from the new string.templatelib module. Not a string. A structured object. type(t"Hello, {name}!") # And here is the heart of it. An f-string does the interpolation eagerly. It grabs the value of name, drops it into the text, and hands you a done string with no memory of which parts were literal and which came from a variable. A t-string does not interpolate into a final string at all. Instead, it keeps the pieces separate: the static text parts on one side, the interpolated values on the other, handed to you as a structured object you can inspect and process before anything becomes a finished string. The f-string gives you the result. The t-string gives you the recipe, with the dangerous ingredients still in their own labeled containers, so a library can treat them differently from the trusted parts before combining them. What a Template Actually Holds Because a Template keeps the pieces apart, you can look at them. It exposes its structure directly: name = "Pythonista" site = "example.dev" template = t"Hello, {name}! Welcome to {site}!" template.strings # ('Hello, ', '! Welcome to ', '!')
This is a summary aggregated from Dev.to. Read the complete article on the original site:
Read full article at Dev.to