TE
TechEcho
Home24h TopNewestBestAskShowJobs
GitHubTwitter
Home

TechEcho

A tech news platform built with Next.js, providing global tech news and discussions.

GitHubTwitter

Home

HomeNewestBestAskShowJobs

Resources

HackerNews APIOriginal HackerNewsNext.js

© 2025 TechEcho. All rights reserved.

Python’s new t-strings

620 pointsby tambourine_man23 days ago

41 comments

serbuvlad23 days ago
All things considered, this is pretty cool. Basically, this replaces<p><pre><code> db.execute(&quot;QUERY WHERE name = ?&quot;, (name,)) </code></pre> with<p><pre><code> db.execute(t&quot;QUERY WHERE name = {name}&quot;) </code></pre> 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:<p>1. Allowing library developers to do whatever they want with {} expansions is a good thing, and will probably spawn some good uses.<p>2. Generalizing template syntax across a language, so that all libraries solve this problem in the same way, is probably a good thing.
评论 #43750513 未加载
评论 #43752173 未加载
评论 #43750750 未加载
评论 #43752117 未加载
评论 #43750250 未加载
评论 #43756560 未加载
评论 #43754738 未加载
评论 #43750260 未加载
评论 #43750279 未加载
评论 #43752293 未加载
评论 #43763190 未加载
评论 #43750226 未加载
florbnit23 days ago
&gt; In addition, I hope that the tooling ecosystem will adapt to support t-strings. For instance, I’d love to see black and ruff format t-string contents, and vscode color those contents, if they’re a common type like HTML or SQL.<p>This is such a strange take on t-strings. The only way for anything to infer that the template string is supposed to turn into valid HTML or SQL is to base it of the apparent syntax in the string, which can only be done in an ad-hoc fashion and has nothing to do with the template string feature.<p>The way the feature has been designed there is no indication in the string itself what type of content it is or what it will eventually be converted to. It’s all handled by the converting function.<p>As others have added, something like sql”select * from {table}” would have been able to do this, but there’s not even any guarantees that something that is in a template that will be converted into valid sql by a converting function should be any type of valid sql prior to that conversion. For all you know t“give me {table} but only {columns}” might be a converted into valid sql after the template is processed.
评论 #43755210 未加载
评论 #43755016 未加载
评论 #43754586 未加载
评论 #43757519 未加载
评论 #43754745 未加载
评论 #43754827 未加载
评论 #43754693 未加载
TekMol23 days ago
Will this allow neat SQL syntax like the following?<p><pre><code> city = &#x27;London&#x27; min_age = 21 # Find all users in London who are 21 or older: users = db.get(t&#x27; SELECT * FROM users WHERE city={city} AND age&gt;{min_age} &#x27;) </code></pre> If the db.get() function accepts a template, it should, right?<p>This would be the nicest way to use SQL I have seen yet.
评论 #43749906 未加载
评论 #43756963 未加载
评论 #43749734 未加载
评论 #43750037 未加载
评论 #43749926 未加载
评论 #43751845 未加载
评论 #43749979 未加载
评论 #43749674 未加载
nu11ptr23 days ago
Personally, this feels like a feature that is too focused on one problem to be a general feature. Python is getting huge. When people ask me if Python is easy and simple to learn I have to say &quot;the basics, yes, but to to learn the whole language... not so much&quot;.<p>I feel like in this sense Go really is interesting by rejecting almost every single feature. Honestly not sure generics were worth it as they add a lot of complexity, and while they are nice, I don&#x27;t need them very much. The general idea to keep the language at its original focus is the right idea IMO. C++ would be the most extreme case where the language itself barely resembles what it started out as.
评论 #43750807 未加载
评论 #43750633 未加载
评论 #43751386 未加载
评论 #43754916 未加载
gnabgib23 days ago
Big discussion (414 points, 10 days ago, 324 comments) <a href="https:&#x2F;&#x2F;news.ycombinator.com&#x2F;item?id=43647716">https:&#x2F;&#x2F;news.ycombinator.com&#x2F;item?id=43647716</a>
评论 #43750057 未加载
runekaagaard23 days ago
It feels a bit like &quot;cheating&quot; that new x-string features are built-in only. It would be cool to be able to do:<p><pre><code> from foo import bar bar&quot;zoop&quot;</code></pre>
评论 #43749594 未加载
评论 #43750748 未加载
评论 #43751130 未加载
评论 #43749601 未加载
评论 #43749709 未加载
评论 #43757083 未加载
评论 #43752217 未加载
mounir991223 days ago
What I really don&#x27;t get is how it&#x27;s any different than applying whatever function you would apply to the template, on the f-string variables. So instead of:<p><pre><code> evil = &quot;&lt;script&gt;alert(&#x27;bad&#x27;)&lt;&#x2F;script&gt;&quot; template = t&quot;{evil}&quot; safe = html(template) </code></pre> Why not just:<p><pre><code> evil = &quot;&lt;script&gt;alert(&#x27;bad&#x27;)&lt;&#x2F;script&gt;&quot; safe = f&quot;{html(evil)}&quot; </code></pre> Or even before creating the f-string. Is it just about not forgetting the sanitization&#x2F;string manipulation part and forcing you to go through that?
评论 #43757122 未加载
评论 #43753514 未加载
nikisweeting23 days ago
This is pretty cool, if we&#x27;re porting JS features do we get dictionary unpacking&#x2F;destructuring next?<p>I just want this so badly, it&#x27;s the main reason I drift back to JS:<p><pre><code> &gt;&gt;&gt; {a, b=45, c=None, **d} = {&#x27;a&#x27;: 234, xzy: 32456} &gt;&gt;&gt; print(a, b, c, d) 234 45 None {&#x27;xyz&#x27;: 32456}</code></pre>
评论 #43757011 未加载
评论 #43754187 未加载
sashank_150923 days ago
Why does this need to be a language feature. This could just be a separate library, we could use brackets instead of a letter before a string. I fear, Python is going down the path of C++
评论 #43749868 未加载
评论 #43751165 未加载
评论 #43750832 未加载
评论 #43750107 未加载
评论 #43751480 未加载
评论 #43749921 未加载
评论 #43749980 未加载
metrognome23 days ago
Zen of Python in 2025:<p><pre><code> There should be one-- and preferably only one --obvious way to do it. </code></pre> Python String Formatting in 2025:<p>- t-strings<p>- f-strings<p>- %-operator<p>- +-operator<p>- str.format()
评论 #43754671 未加载
评论 #43754501 未加载
评论 #43756716 未加载
评论 #43756756 未加载
nezirus23 days ago
Maybe this could be useful to libraries like psycopg3 to use something more simple&#x2F;natural instead of this:<p><a href="https:&#x2F;&#x2F;www.psycopg.org&#x2F;psycopg3&#x2F;docs&#x2F;api&#x2F;sql.html" rel="nofollow">https:&#x2F;&#x2F;www.psycopg.org&#x2F;psycopg3&#x2F;docs&#x2F;api&#x2F;sql.html</a><p>(while I also agree it gets crowded with yet another string prefix)
评论 #43749372 未加载
davepeck23 days ago
Hi! I wrote this. :-)<p>I&#x27;m a little late to the conversation (and a bit surprised to see this trending on HN) but am happy to answer any questions; I&#x27;ll try to pop in throughout the day.
评论 #43754336 未加载
评论 #43754430 未加载
评论 #43754275 未加载
mos_basik23 days ago
Landing in 3.14? Nice, but also oof, that&#x27;s probably not getting to my employer&#x27;s codebase for a year or two. And it sounds like it could really solve some problems for us, too.<p>Paging asottile - any plans to make a `future-tstrings`? :)<p>`future-fstrings` (<a href="https:&#x2F;&#x2F;pypi.org&#x2F;project&#x2F;future-fstrings&#x2F;" rel="nofollow">https:&#x2F;&#x2F;pypi.org&#x2F;project&#x2F;future-fstrings&#x2F;</a>) was a real QOL improvement for our team for a year or 2 around 2019 before we got onto Python 3.x.
评论 #43755099 未加载
评论 #43755409 未加载
fph23 days ago
How do these interact with i18n? Can I load a translated t-string with `_(t&quot;&quot;)` from a .po file? Can it include variable names and arbitrary code inside lambdas?
评论 #43751188 未加载
pansa223 days ago
&gt; <i>t-strings evaluate to a new type, `string.templatelib.Template`</i><p>&gt; <i>To support processing, `Template`s give developers access to the string and its interpolated values </i>before* they are combined into a final string.*<p>Are there any use-cases where processing a Template involves something other than (i) process each value, then (ii) recombine the results and the string parts, in their original order, to produce a new string? In other words, is the `process_template` function ever going to be substantially different from this (based on `pig_latin` from the article)?<p><pre><code> def process_template(template: Template) -&gt; str: result = [] for item in template: if isinstance(item, str): result.append(item) else: result.append(process_value(item.value)) return &quot;&quot;.join(result) </code></pre> I haven&#x27;t seen any examples where the function would be different. But if there aren&#x27;t any, it&#x27;s strange that the design requires every Template processing function to include this boilerplate, instead of making, say, a `Template.process` method that accepts a `process_value` function.
评论 #43753470 未加载
评论 #43750478 未加载
评论 #43757222 未加载
franga200023 days ago
I wish they added the same thing JS has, where this &quot;string literal prefix thingy&quot; can be user-defined.<p>html`&lt;p&gt;${value}&lt;&#x2F;p&gt;` will actually run the function html(template). This means you can use this to &quot;mark&quot; a function in a way that can be detected by static analysis. Many editors will, for example, syntax highlight and lint any HTML marked this way, same with SQL, GraphQL and probably some others too.
评论 #43751094 未加载
评论 #43750403 未加载
TheRealPomax23 days ago
&gt; If you’ve worked with JavaScript, t-strings may feel familiar. They are the pythonic parallel to JavaScript’s tagged templates.<p>The syntax is template literals, not just &quot;tagged templates&quot;. Which is a <i>huge</i> difference: template literals still act as real strings. They don&#x27;t <i>need</i> a tag prefix to work, you have the <i>option</i> to tag them if and when needed.<p>As far as I understand it, t-strings can&#x27;t do that. They&#x27;re not strings, and you can&#x27;t even coerce them into strings, you <i>have</i> to run them through a processor before they become a string. So they&#x27;re nothing like JS&#x27;s template literals, they&#x27;re syntactic sugar for forming &quot;an instance of an object that needs to be passed into a function that returns a string&quot;.<p>So I don&#x27;t look forward to folks preferring f-strings over t-strings even when they really shouldn&#x27;t, simply because &quot;having to constantly convert them from not-a-string to a string is a hassle&quot;. If only they&#x27;d worked like JS template literals.. that would have been <i>fantastic</i>.
pizza23 days ago
Looks useful for embedding interpreters
sgt23 days ago
Will it be a performance boost if Django&#x27;s template engine started using t-strings internally?
评论 #43749940 未加载
pragma_x23 days ago
Debate around the usefulness aside, are there any linter rules for warning about f-strings in light of this? I can easily see where mistaking one for the other would cause problems. For context, I&#x27;m thinking specifically about tools like Black and MyPy.
评论 #43751430 未加载
评论 #43752295 未加载
oulipo23 days ago
Nice, so it&#x27;s a kind of &quot;limited DSL&quot; inside python that&#x27;s easy to extend
评论 #43754788 未加载
est23 days ago
<a href="https:&#x2F;&#x2F;peps.python.org&#x2F;pep-0750&#x2F;#approaches-to-lazy-evaluation" rel="nofollow">https:&#x2F;&#x2F;peps.python.org&#x2F;pep-0750&#x2F;#approaches-to-lazy-evaluat...</a><p>name = &quot;World&quot;<p>template = t&quot;Hello {(lambda: name)}&quot;<p>This looks cool
haberman23 days ago
TL;DR: like f-strings, all {foo} expressions in the t-string are evaluated immediately, but instead of immediately concatenating everything into a single result string, the t-string evaluation returns a Template object that keeps the interpolation results and the surrounding strings separate. This lets subsequent logic decide whether the interpolation results need any special escaping before concatenating them with the strings around them.<p>In other words, t-strings are basically f-strings where the final concatenation is delayed. And indeed, you can trivially implement f-strings using t-strings by performing a simple, non-escaped concatenation step: <a href="https:&#x2F;&#x2F;peps.python.org&#x2F;pep-0750&#x2F;#example-implementing-f-strings-with-t-strings" rel="nofollow">https:&#x2F;&#x2F;peps.python.org&#x2F;pep-0750&#x2F;#example-implementing-f-str...</a><p><pre><code> f&#x27;...&#x27; -&gt; str t&#x27;...&#x27; -&gt; Template foo(t: Template) -&gt; str</code></pre>
评论 #43753056 未加载
kamikaz1k23 days ago
by making it a generic `t` you lose explicit syntax highlighting. Where something like JS template`string` could determine which syntax to use based on the template value.<p>I supposed when assigning it to a, variable: SyntaxRecognizableTemplate, you could give it the hint necessary.<p>was this discussed in the PEP?<p>*edit: reading the PEP-750[1] it doesn&#x27;t seem like it..<p>[1] <a href="https:&#x2F;&#x2F;peps.python.org&#x2F;pep-0750&#x2F;#the-interpolation-type" rel="nofollow">https:&#x2F;&#x2F;peps.python.org&#x2F;pep-0750&#x2F;#the-interpolation-type</a>
评论 #43754598 未加载
评论 #43754660 未加载
feraidoon23 days ago
I had something like this implemented for safely executing shell commands, by using metaprogramming:<p>name=&quot;A$ron&quot;<p>z(&quot;echo Hello {name}&quot;)<p>Note that this is not an f-string. The z function expands the variables by parsing this string and accessing its caller&#x27;s local variables.<p><a href="https:&#x2F;&#x2F;github.com&#x2F;NightMachinery&#x2F;brish">https:&#x2F;&#x2F;github.com&#x2F;NightMachinery&#x2F;brish</a>
enescakir23 days ago
Not sure about introducing yet another string prefix. Between f-strings, raw strings, and i18n stuff, it’s already getting crowded. Curious how readable this will be in large codebases.
评论 #43749334 未加载
评论 #43749489 未加载
评论 #43749515 未加载
vFunct23 days ago
Would like to see Django fully use these to replace a lot of it&#x27;s own complicated template syntax.
toxik23 days ago
So should f strings now go away? They are just a special case of t strings.<p>Also, don’t get me started on g strings.
评论 #43750119 未加载
评论 #43751209 未加载
pauleveritt22 days ago
As an example of t-strings helping SQL, Phil Jones published a package [1] that illustrates how it could work.<p>[1] <a href="https:&#x2F;&#x2F;github.com&#x2F;pgjones&#x2F;sql-tstring">https:&#x2F;&#x2F;github.com&#x2F;pgjones&#x2F;sql-tstring</a>
morkalork23 days ago
Honestly think this is a more useful feature and elegant solution than the walrus operator that was added. Formatting query strings has always felt messy especially with different DBs having their own non-standard ways of doing it.
mont_tag23 days ago
How does this Python docs example work with t-strings?<p><pre><code> cur.executemany(&quot;INSERT INTO movie VALUES(?, ?, ?)&quot;, data) </code></pre> Can SQLite3 cache the query as it does now?
评论 #43754460 未加载
bk49622 days ago
Lowercase f is very visually similar to t. Hopefully no bugs occur from a typo
dec0dedab0de23 days ago
Seems pretty neat so far, but I don&#x27;t understand the motivation behind not allowing you to call str(template) and get the template as a normal string. I could imagine it being very useful to be able to gather up the template itself in a string to do stringy things with.<p>The only reason I could imagine, is if you are trying to protect developers from themselves, which kinda goes against the &quot;we&#x27;re all adults here&quot; mentality that makes Python so great. I suppose it&#x27;s easy enough to add that functionality, but come on.
评论 #43752172 未加载
0xFEE1DEAD23 days ago
Call me a monarchist, but I think Python has changed for the worse ever since Guido van Rossum stepped down.
评论 #43750497 未加载
评论 #43753657 未加载
评论 #43756856 未加载
评论 #43751193 未加载
permo-w23 days ago
is this just a copy paste of the PEP announcement?
avereveard23 days ago
what&#x27;s the tldr difference between this and .format ?
评论 #43749190 未加载
评论 #43749636 未加载
评论 #43750013 未加载
评论 #43749387 未加载
m2f223 days ago
If this is just for sql queries ... it&#x27;d be overkill especially where you need to compare the usual PREPARE statements with the hassle of keeping everyone on 3.14 and above.
评论 #43751693 未加载
评论 #43749704 未加载
评论 #43751238 未加载
773412823 days ago
Sure, this avoids issues with SQL injections. However, I have a hard time imagining any developer who would both make such fundamental errors with f-strings currently and also switching to this option when it ships.<p>Seems like a self selection which renders this meaningless, to some extent :&#x2F;
评论 #43749587 未加载
评论 #43756893 未加载
russfink23 days ago
I feel like this can be solved another way. S=f”my good code #### {potentially_evil_user_input} #### my good code again” then work around the ####. Of course, even better, S=evil_user_input and do a scrub on S first.
评论 #43751304 未加载
Smithalicious23 days ago
I really was on the side of being generally willing to accept new python features, but this is getting ridiculous. What an utterly pointless thing to bloat the language with. At this point my moving to clojure as my first line language of choice is only accelerating.<p>This is of the category &quot;things I wouldn&#x27;t want to use even for the specific hyper niche things they&#x27;re intended for&quot;. What even does a &quot;t-string&quot; represent? Because it&#x27;s clearly not a string of any kind, it&#x27;s a weird kind of function call notation. The programmer sees something that looks like string formatting, but the program executes some arbitrary procedure that might not return a string whatsoever.
评论 #43751148 未加载
评论 #43751503 未加载
damnitbuilds23 days ago
I enjoy f-strings, I guess some people need these.<p>And I love Python but, having been through 2-&gt;3 ( occasionally still going through it! ) whenever I see a new language feature my first thought is &quot;Thank goodness it doesn&#x27;t break everything that went before it&quot;.
评论 #43749513 未加载