3 ms·
> It should have used something with a limited list of named arguments, or maybe a dict. That's what "old-style" python interpolation did :) You could do |"hi
by Manishearth 10y ago
> It should have used something with a limited list of named arguments, or maybe a dict.
That's what "old-style" python interpolation did :)
You could do |"hi my name is %s and I live in %s" % (name, place)| or use named arguments with a dict (|"hi my name is %(name) and I live in %(place)" % {"name": name, "place": place}|).
I like JS format strings -- you can write arbitrary code in them, but they are compile time only (and use a different string syntax). So you can have |`Hello my name is ${name} and I come from ${place}. My profession is ${generate_random_profession()}`|. The backtick-string isn't a different type, and can't be moved around like a value. It's a different kind of way of specifying a string literal, and will be evaluated when specified. No way of doing injection there.
I suspect Python wanted to make it less verbose with new-style interpolation, and went a bit overboard with field access without realizing or caring about possible security issues like this.
Of course, python has a third kind of format string; interpolation string literals (|f"hello my name is {name} ..."|), which work like JS and Ruby. This is what you should be using IMO.
- saghm 10y ago> I like JS format strings -- you can write arbitrary code in them, but they are compile time only Genuinely curious: what exactly does "compile-time" mean in the case of JS? Is it like C macros (modifying the source code before parsing)?
- Manishearth 10y agoNo, it's not that, I was using the term loosely. I meant that you cannot use a string value as a format string. It only exists in the form of a literal, and it gets evaluated when the interpreter evaluates that literal. You cannot store it and format it later.
- saghm 10y agoAh, I see. Thanks!