On Fri, Dec 3, 2021 at 2:24 PM Steven D'Aprano email@example.com wrote:
On Fri, Dec 03, 2021 at 01:08:50PM +1100, Chris Angelico wrote:
How, with external calling, are you going to know which name references to look up, and where to get their values from?
Isn't the source code available as a string? I will see the names in the expression.
Or I will disassemble the code object and inspect its byte-code and/or AST. Or read the documentation. Or maybe the code object will expose those names in a dunder and I can just look at that.
This is already a virtually impossible task in Python, which is why f-strings cannot be implemented as str.format(**something) for any known meaning of "something".
f-strings cannot be implemented as str.format because str.format doesn't evaluate arbitrary expressions.
You cannot get your *current* variable set, much less the available variables in some other context.
Why not? The default expression object can record nonlocal variables in a closure, and you can provide your own globals and/or locals.
You're saying "can't, impossible" but I could take your function object, extract the code object, disassemble the code to AST or byte-code, extract the portions that represent the default expression, and evaluate that. So not *impossible*, just bloody inconvenient and annoying.
(Well, when I say *I could*, I mean *somebody with mad leet AST or byte- code hacking skillz. Not actually me.)
When f-strings were first proposed, one of the counter-arguments was basically "just use globals()/locals()".
But you cannot, in a fully general way, solve the problem that way. It is *impossible*. Not just difficult. Impossible. You cannot, in Python as it currently is, look up arbitrary names in any reliable way. This is especially true now that we have assignment expressions, such that evaluating the function default could create a new local or nonlocal name.
Not just inconvenient and annoying. So impossible that a str method could not be written to do it.