This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author eric.smith
Recipients Allie Fitter, a.badger, eric.smith
Date 2019-07-24.23:43:49
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <>
I've put some more thought in to this, and this is the best I can come up with, using today's Python.

The basic idea is that you have a function _f(), which takes a normal (non-f) string. It does a lookup to find the translated string (again, a non-fstring), turns that into an f-string, then compiles it and returns the code object. Then the caller evals the returned code object to convert it to a string.

The ugly part, of course, is the eval. You can't just say:
you have to say:
You can't reduce this to a single function call: the eval() has to take place right here. It is possible to play games with stack frames, but that doesn't always work (see PEP 498 for details, where it talks about locals() and globals(), which is part of the same problem).

But I don't see much choice. Since a translated f-string can do anything (like f'{"script to rm all files")'), I'm not sure it's the eval that's the worst thing here. The translated text absolutely has to be trusted: that's the worst thing. Even an eval_fstring(), that only understood how to exec code objects that are f-strings, would still be exposed to arbitrary expressions and side effects in the translated strings.

The advantage of compiling it and caching is that you get most of the performance advantages of f-strings, after the first time a string is used. The code generation still has to happen, though. It's just the parsing that's being saved. I can't say how significant that is.

See the sample code in the attached file.
Date User Action Args
2019-07-24 23:43:49eric.smithsetrecipients: + eric.smith, a.badger, Allie Fitter
2019-07-24 23:43:49eric.smithsetmessageid: <>
2019-07-24 23:43:49eric.smithlinkissue36310 messages
2019-07-24 23:43:49eric.smithcreate