On 27/01/2023 23:41, Chris Angelico wrote:
On Sat, 28 Jan 2023 at 10:08, Rob Cliffe via Python-list
<python-list@python.org>  wrote:
Whoa! Whoa! Whoa!
I appreciate the points you are making, Chris, but I am a bit taken
aback by such forceful language.
The exact same points have already been made, but not listened to.
Sometimes, forceful language is required in order to get people to
listen.

If it's addressed to me:  How about if I wanted a program (a learning
tool) to allow the user to play with f-strings?
I.e. to type in a string, and then see what the result would be if it
had been an f-string?
I suspect there are other use cases, but I confess I can't think of one
right now.
Use the REPL, which will happily evaluate f-strings in their original
context, just like any other code would. You're already eval'ing, so
it's exactly what you'd expect. This is not the same thing as "typing
in a string", though - it's typing in code and seeing what the result
would be. (Except to the extent that source code can be considered a
string.)
This is hypothetical, but I might want to work on a platform where the REPL was not available.

If it's addressed to me: "it" means a function that will take a string
and evaluate it at runtime as if it were an f-string.  Sure, with
caveats and limitations.
And that's what I am saying is a terrible terrible idea. It will
evaluate things in the wrong context, it has all the normal problems
of eval, and then it introduces its own unique problems with quote
characters.
With great respect, Chris, isn't it for the OP (or anyone else) to decide - having been warned of the various drawbacks and limitations - to decide if it's a terrible idea *for him*?  He's entitled to decide that it's just what *he* needs, and that the drawbacks don't matter *for him".  Just as you're entitled to disagree.

  And indeed Thomas Passim found this partial
solution on Stack Overflow:
def effify(non_f_str: str):
      return eval(f'f"""{non_f_str}"""')
You can find anything on Stack Overflow. Just because you found it
there doesn't mean it's any good - even if it's been massively
upvoted.

Addressing your points specifically:
      1) I believe the quote character limitation could be overcome. It
would need a fair amount of work, for which I haven't (yet) the time or
inclination.
No problem. Here, solve it for this string:

eval_me = ' f"""{f\'\'\'{f"{f\'{1+2}\'}"}\'\'\'}""" '

F-strings can be nested, remember.
I remember it well.
As far as I can see (and I may well be wrong; thinking about this example made my head hurt 😁) this could be solved if PEP 701 were implemented (so that f-string expressions can contain backslashes) but not otherwise.

      2) Yes in general you would have to pass it one dictionary, maybe
two.  I don't see this as an insuperable obstacle.  I am not sure what
you mean by "can't be done with full generality" and perhaps that's not
important.
def func():
...     x = 1
...     class cls:
...             y = 2
...             print(f"{x=} {y=}")
...             print(locals())
...
func()
x=1 y=2
{'__module__': '__main__', '__qualname__': 'func.<locals>.cls', 'y': 2}
Thanks for clarifying.
Hm.  So 'x' is neither in locals() nor in globals().  Which starts me wondering (to go off on a tangent): Should there be a nonlocals() dictionary?

Maybe you don't care. Maybe you do. But locals() is not the same as
"all names currently available in this scope". And, this example is
definitely not something I would recommend, but good luck making this
work with eval:

def func():
...     x = 1
...     print(f"{(x:=2)}")
...     print(x)
...
func()
2
2
...     x = 1
...     print(eval("(x:=2)", globals(), locals()))
...     print(x)
...
func()
2
1
Now that, I have to admit, IS a challenge!

      3) Not sure I understand this.
Before f-strings existed, one of the big problems with "just use
str.format_map" was that you can't just pass it locals() to get all
the available names. You also can't eval arbitrary code and expect to
get the same results, even if you pass it globals and locals. And
various other considerations here - the exact issues seen here, but
flipped on their heads. So the obvious question is: why not just use
str.format_map?

What this underlines to me is what a good thing f-strings are.  And with PEP 701 they will be IMO even better. Just as when you were working on PEP 463 (Exception-catching expressions) - which I still think would be a Good Thing - some research I did made me realise how good the existing try/except/else/finally mechanism actually is.  There's lots of Good Stuff in Python. 😁
Best wishes
Rob


--
https://mail.python.org/mailman/listinfo/python-list

Reply via email to