I'd used f-string-like syntaxes in other languages before they came to Python. It was immediately obvious to me what the benefit would be.
I've used assignment expressions in other languages too! Python's version doesn't suffer from the JavaScript problem whereby equality and assignment are just a typo apart in, eg., the condition of your while loop. Nonetheless, I find that it ranges from marginally beneficial to marginally confusing in practice.
I love string interpolation! But this seems to take it to a bizarre level place just to save a few keystrokes. Seriously, how is f"{now=!s}" substantially better than f"now={str(now)}"?
Ergonomically, I see little benefit for the added complexity.
It really feels like it's very explicit at this point that you want to cast whatever value interpolated into your format string to a string...
I don't want a type error for the most clear use case, in the same way I don't want one for print, because if I wanted a behaviour other than the basic string representation then I would still need to call something differently anyway.
Given that explicit control of the __str__ method is also baked into the language it's also very clear what to expect.
I like type errors when handling something like '1' + 1 because the JavaScript alternative is surprising and hides bugs. No surprises that a string formatter would coerce to string for me automatically (although I get that's maybe just personal feeling).
I love the f strings, they have made my codebase cleaner and clearer. Definitely a pythonic win.
In GP's example, the call to str() isn't there to make sure you get a string instead of causing a type error; it's there to substitute str() for repr() (which also returns a string). Considering that this feature is mainly meant to make 'print debugging' more convenient, it makes sense that repr() is the default choice.
I've used assignment expressions in other languages too! Python's version doesn't suffer from the JavaScript problem whereby equality and assignment are just a typo apart in, eg., the condition of your while loop. Nonetheless, I find that it ranges from marginally beneficial to marginally confusing in practice.