7 ms·
The t-string produces a Template object without a __str__() method. You can’t mistakenly use an f-string in its place. Either the code expects a string, in whic
by JimDabell 2y ago
The t-string produces a Template object without a __str__() method. You can’t mistakenly use an f-string in its place. Either the code expects a string, in which case passing it a Template would blow it up, or the code expects a Template, in which case passing it a string would blow it up.
- politelemon 2y agoAnd I'm guessing lots of code will expect strings to maintain backward compatibility.
- Mawr 2y agoI'm guessing no existing functions will be extended to allow t-strings for this very reason. Instead, new functions that only accept t-strings will be created.
- xorcist 2y agoThere's an obvious risk here, same as with strcpy (no, strncpy.. no, strlcpy... no, strcpy_s) that documentation tends to outlive code, and people keep pasting from tutorails and older code so much that the newer alternatives have a hard time cutting through the noise. I would argue that as bad as some w3schools tutorials were, and copying from bad Stackoverflow answers, going back to MSA and the free cgi archives of the 90s, the tendency of code snippets to live on forever will only be excarbated by AI-style coding agents. On the other hand, deprecating existing methods is what languages do to die. And for good reason. I don't think there's an easy answer here. But language is also culture, and shared beliefs about code quality can be a middle route between respecting legacy and building new. If static checking is as easy as a directive such as "use strict" and the idea that checking is good spreads, then consesus can slowly evolve while working code keeps working.
- sanderjd 2y agoIt's pretty common for Python libraries to deprecate and remove functionality. It makes people mad, but it's a good thing, for this reason.
- tubthumper8 2y agoDo the python type checkers / linters / whatever have the ability to warn or error on calling certain functions? That would be nice to eventually enforce migration over to the newer functions that only take a t-string template
- mb5 2y agoThey sure do, e.g. https://docs.astral.sh/ruff/rules/pandas-use-of-dot-is-null/ https://docs.astral.sh/ruff/rules/pandas-use-of-dot-is-null/
- mos_basik 2y agoYeah. A while back I was poking through some unfamiliar code and noticed that my editor was rendering a use of `datetime.utcnow()` as struck through. When I hovered it with my mouse, I got a message that that function had been deprecated. Turns out my editor (vscode) and typechecker (pyright) saw that `datetime.utcnow()` was marked as deprecated (I know one can use the `@deprecated` decorator from Python 3.13 or `__future__` to do this; I think it was done another way in this particular case) and therefore rendered it as struck through. And it taught me A) that `utcnow()` is deprecated and B) how to mark bits of our internal codebase as deprecated and nudge our developers to use the new, better versions if possible.
- tubthumper8 2y agoCan you do it for functions defined by other people, or only for functions that you defined? I'm thinking in the general case, but motivated by this example of a 3rd party function that accepts a SQL query as a string, and we'd like everywhere in our codebase to stop using that and instead use the 3rd party function that accepts the query as a t-string
- sanderjd 2y agoI think it's way more likely that existing libraries will introduce new methods that use t-strings and are type safe, rather than entirely defeat the purpose of having a t-string API.
- b3orn 2y agoIf it's not a completely new library written exclusively around templates, such code currently accepts strings and will most likely continue to accept strings for backwards compatibility.
- keybored 2y agoIn that case I don’t understand the security regression that t-strings cause (see GP). Before it was all just strings, but you had to make sure to use them in the correct place. Now you can still just use strings for backwards compat. but you can also move on to a distinctly-typed solution for SQL and the like.
- yk 2y agoThat's entirely implementation dependent. For existing libraries I would expect something like def get(self, query): if isinstance(query, template): self.get_template(query) else: self.get_old(query) #Don't break old code!
- ewidar 2y agoit would likely be safer to have a safe (accepting Templates) and an unsafe (accepting strings) interface. Now whether maintainers introduce `getSafe` and keep the old behavior intact, or make a breaking change to turn `get` into `getUnsafe`, we will see
- darthwalsh 2y agoAnd they could add deprecation warnings gradually
- solatic 2y agoThat would be a great argument if Python wasn't a language that let you reach into the internals and define __str__() for things you shouldn't be defining it for. And that is something people will definitely do because, you know, they just need something to friggin work so they can get whatever ticket closed and keep some metric happy tracking time-to-close
- scott_w 2y agoProgrammers being lazy and shit at their jobs is not a reason to not improve the language.
- crazygringo 2y ago> or the code expects a Template, in which case passing it a string would blow it up. That's where the problem is though -- in most cases it probably won't blow up. Plenty of SQL queries don't have any parameters at all. You're just getting the number of rows in a table or something. A raw string is perfectly fine. Will sqlite3 really disallow strings? Will it force you to use templates, even when the template doesn't contain any parameters? You can argue it should, but that's not being very friendly with inputs, and will break backwards compatibility. Maybe if there's a flag you can set in the module to enable that strict behavior though, with the idea that in a decade it will become the default?
- WorldMaker 2y agodb.execute(t"Select Count(1) from someTable") It's one extra letter to "force" for an unparameterized query over a "raw string". The t-string itself works just fine without parameters. There's definitely a backwards compatibility hurdle of switching to a template-only API, but a template-only API doesn't look that much "less friendly" with inputs, when the only difference is a `t` before every string, regardless of number of parameters.
- crazygringo 2y agoSure, but it's just I don't have to do that anywhere else. I never put an f in front of a string if I'm not putting variables within it. And I'm generally used to Python inputs being liberal. I can usually pass a list if it expects a tuple; I can pass an int if it expects a float; often I can pass an item directly instead of a tuple with a single item. Regex functions take regular strings or regex strings, they don't force regex strings. Being forced to use a single specific type of string in all cases is just very different from how Python has traditionally operated. It's safer, I get that. But it's definitely less friendly, so I'll be curious to see how module maintainers decide to handle this.
- scott_w 2y agoEr… that’s just not correct? Python can be more liberal but it’s not always. It depends entirely on the tooling. Libraries will take time to catch up but I can definitely see people creating libraries that enforce t-strings, even if they’re deconstructing them under the hood for legacy libraries.