Evaluation of variable as f-string
Johannes Bauer
dfnsonfsduifb at gmx.de
Fri Jan 27 15:31:05 EST 2023
Am 23.01.23 um 19:02 schrieb Chris Angelico:
>> This is supposedly for security reasons. However, when trying to emulate
>> this behavior that I wanted (and know the security implications of), my
>> solutions will tend to be less secure. Here is what I have been thinking
>> about:
>
> If you really want the full power of an f-string, then you're asking
> for the full power of eval(),
Exactly.
> and that means all the security
> implications thereof,
Precisely, as I had stated myself.
> not to mention the difficulties of namespacing.
Not an issue in my case.
> Have you considered using the vanilla format() method instead?
Yes. It does not provide the functionality I want. Not even the utterly
trivial example that I gave. To quote myself again, let's say I have an
arbitrary dictionary x (with many nested data structures), I want an
expression to be evaluated that can access any members in there.
x = { "y": "z" }
s = "-> {x['y']}"
print(s.format(x = x))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: "'y'"
I also want to be able to say things like {'x' * 100}, which .format()
also does not do.
In other words: I want the evaluation of a variable as an f-string.
> But if you really REALLY know what you're doing, just use eval()
> directly.
I do, actually, but I hate it. Not because of the security issue, not
because of namespaces, but because it does not reliably work:
>>> s = "{\"x\" * 4}"
>>> eval("f'" + s + "'")
'xxxx'
As I mentioned, it depends on the exact quoting. Triple quotes only
shift the problem. Actually replacing/escaping the relevant quotation
marks is also not trivial.
> I don't really see what you'd gain from an f-string.
The full power of eval.
> At very
> least, work with a well-defined namespace and eval whatever you need
> in that context.
That's what I'm doing.
> Maybe, rather than asking for a way to treat a string as code, ask for
> what you ACTUALLY need, and we can help?
I want to render data from a template using an easily understandable
syntax (like an f-string), ideally using native Python. I want the
template to make use of Python code constructs AND formatting (e.g.
{x['time']['runtime']['seconds'] // 60:02d}).
Cheers,
Johannes
More information about the Python-list
mailing list