←back to thread

620 points tambourine_man | 1 comments | | HN request time: 0s | source
Show context
serbuvlad ◴[] No.43750075[source]
All things considered, this is pretty cool. Basically, this replaces

    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:

1. Allowing library developers to do whatever they want with {} expansions is a good thing, and will probably spawn some good uses.

2. Generalizing template syntax across a language, so that all libraries solve this problem in the same way, is probably a good thing.

replies(12): >>43750226 #>>43750250 #>>43750260 #>>43750279 #>>43750513 #>>43750750 #>>43752117 #>>43752173 #>>43752293 #>>43754738 #>>43756560 #>>43763190 #
Tenoke ◴[] No.43750250[source]
I don't see what it adds over f-string in that example?
replies(6): >>43750258 #>>43750261 #>>43750262 #>>43750265 #>>43750295 #>>43750581 #
burky ◴[] No.43750262[source]
f-strings won’t sanitize the value, so it’s not safe. The article talks about this.
replies(1): >>43750427 #
Tenoke ◴[] No.43750427[source]
The article talked about it but the example here just assumes they'll be there.
replies(2): >>43751261 #>>43751285 #
sanderjd ◴[] No.43751261[source]
What do you mean by "they"? You mean the template interpolation functions?

Yes, the idea is that by having this in the language, library authors will write these implementations for use cases where they are appropriate.

replies(1): >>43751976 #
Tenoke ◴[] No.43751976[source]
The sanitization. Just using a t-string in your old db.execute doesn't imply anything safer is going on than before.
replies(2): >>43752377 #>>43752677 #
masklinn ◴[] No.43752377[source]
Using a t-string in a db.execute which is not compatible with t-strings will result in an error.

Using a t-string in a db-execute which is, should be as safe as using external parameters. And using a non-t-string in that context should (eventually) be rejected.

replies(1): >>43752480 #
Tenoke ◴[] No.43752480[source]
Again, just because a function accepts a t string it doesn't mean there's sanitization going on by default.
replies(1): >>43752636 #
tikhonj ◴[] No.43752636[source]
Yes, but if a function accepts a template (which is a different type of object from a string!), either it is doing sanitization, or it explicitly implemented template support without doing sanitization—hard to do by accident!

The key point here is that a "t-string" isn't a string at all, it's a new kind of literal that's reusing string syntax to create Template objects. That's what makes this new feature fundamentally different from f-strings. Since it's a new type of object, libraries that accept strings will either have to handle it explicitly or raise a TypeError at runtime.

replies(1): >>43753556 #
Tenoke ◴[] No.43753556[source]
I'm not sure why you think it's harder to use them without sanitization - there is nothing inherent about checking the value in it, it's just a nice use.

You might have implemented the t-string to save the value or log it better or something and not even have thought to check or escape anything and definitely not everything (just how people forget to do that elsewhere).

replies(1): >>43753640 #
sanderjd ◴[] No.43753640[source]
I really think you're misunderstanding the feature. If a method has a signature like:

    class DB:
        def execute(query: Template):
            ...
It would be weird for the implementation to just concatenate everything in the template together into a string without doing any processing of the template parameters. If you wanted an unprocessed string, you would just have the parameter be a string.
replies(1): >>43754238 #
Tenoke ◴[] No.43754238[source]
I'm not. Again, you might be processing the variable for logging or saving or passing elsewhere as well or many other reasons unrelated to sanitization.
replies(3): >>43754564 #>>43754600 #>>43755078 #
1. Ukv ◴[] No.43754600[source]
The original comment said that it'd replace

    db.execute("QUERY WHERE name = ?", (name,))
with

    db.execute(t"QUERY WHERE name = {name}")
It's true that in theory `db.execute` could ignore semantics and concatenate together the template and variables to make a string without doing any sanitisation, but isn't the same true of the syntax it was claimed to replace?

Just because templates (or the previous syntax of passing in variables separately) could be used in a way that's equivalent safety-wise to an f-string by a poorly designed library does not mean that they add nothing over an f-string in general - they move the interpolation into db.execute where it can do its own sanitization and, realistically, sqlite3 and other libraries explicitly updated to take these will use it to do proper sanitization.