Remix.run Logo
thayne 5 days ago

Even if you accept that "web" is niche (which I don't), and all your input is trusted not to be malicious (which is not necessarily true for non-web applications, especially if they are privileged), you still need to worry about input with special characters causing bugs. Web apps don't have a monopoly on using a database, or generating strings in a specific syntax that includes user input.

With respect to compilation, that is basically is how t-strings work, but it is the python interpreter that does the compilation. When it parses the t-string, it compiles it to (byte) code to generate a Template object from from the expressions in scope when it is evaluated, which may happen more than once. And if you really want a template that is a separate object that is passed the values separately, you can just wrap a t-string in a function that takes the parameters as arguments.

> two dozen templating libraries that offer much more comprehensive safe and fast text-generation solutions than what t-strings do

But t-strings allow those libraries to be safer (users are less likely to accidentally interpolate values in an f-string, if a t-string is required) and possibly faster (since the python interpreter does the hard work of splitting up the string for you. t-strings don't replace those libraries, it allows them to be better.

bjourne 5 days ago | parent [-]

In non-web contexts untrusted input is not interpolated into the executable streams so you don't worry about special characters. E.g., there is no point in "sanitizing" the name of a variable in a C compiler.

> And if you really want a template that is a separate object that is passed the values separately, you can just wrap a t-string in a function that takes the parameters as arguments.

No, you can't do that: "Template strings are evaluated eagerly from left to right, just like f-strings. This means that interpolations are evaluated immediately when the template string is processed, not deferred or wrapped in lambdas." Every function evaluation creates a new Template object, it does not reuse a precompiled one.

> and possibly faster

Possibly not, since precompilation is not supported.

thayne 5 days ago | parent [-]

> In non-web contexts untrusted input is not interpolated into the executable streams so you don't worry about special characters

I don't know what you mean by `executable` streams, but besides databases as I've already mentioned, a common thing that shows up in non-web applications is invoking a shell command that includes a user-supplied file name as part of it. Currently doing so safely means you need to call `shlex.quote` or similar on the filename, but with t-strings you could have something like: `shell(t"some-command {filename} 2> somefile | other-command")`.

And that is just one specific example. There are other cases it might be useful as well, like say generating an XML configuration file from a template that includes user-supplied input.

> No, you can't do that... Every function evaluation creates a new Template object, it does not reuse a precompiled one.

The code that generates that Template object is pre-compiled though.

If you define a function like:

    def my_template(a, b,c):
        return t"a={a} b={b} c={c}"
When python parses that, it will generate bytecode equivalent to:

    def my_template(a, b,c):
        return Template("a=", Interpolation(a, ...), " b=", Interpolation(b, ...), " c=", Interpolation(c,...))
yes, it does create a new `Template` object every time `my_template` is called, but it doesn't have to re-parse the template string each time, which is an improvement over existing APIs that do re-parse a template string every time it is used.