Search code examples
pythonpython-3.xf-string

How do I convert a string into a formatted string literal at run-time?


I am working my way through PEP 498. Maybe I do not quite get the concept, but how could I possibly convert a regular Python string into a formatted string literal and evaluate it at run-time?


Imagine you have a string:

some_string = 'Name: {name}'

If it was a formatted string literal, the following would work:

name = 'Demo'
some_string_literal = f'Name: {name}'
some_string_literal == 'Name: Demo' # returns True

Ignoring the question of whether this makes sense at all, how could I e.g. read the contents of some_string from a file at run-time, turn it into some_string_literal and evaluate it? My understanding of the underlying CPython implementation is that string literals are interpreted at compile-time (translation into byte code).

I am aware of the more "explicit" option of just using ...

some_string = 'Name: {name}'
some_string.format(name = 'Demo') == 'Name: Demo' # returns True

... but this is not what I am looking for.


EDIT: It was noted in the comments that the "explicit" option is what I should be looking for. I'd agree that what I am asking here is definitely insecure in a number of ways. Nevertheless, I am interested in whether there is a way to do this or not.


Solution

  • PEP 498 says

    Because the compiler must be involved in evaluating the expressions contained in the interpolated strings, there must be some way to denote to the compiler which strings should be evaluated.

    In other words, the f has an effect on the way the string literal is parsed, just as r does. So you have to invoke the parser for the interpolation to work.

    You want to read data into some_string and turn it into a string literal that can be parsed as an f-string. That is not very different from wanting to read data into some_lambda_expression and turning it into a lambda expression. You can do it, of course, using eval, because eval is a way to turn the contents of a string variable into code, by invoking the parser. I know that is not what you wanted. But you can't parse some_string as an f-string without invoking the parser, so you can't have what you want.