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