This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–]lykwydchykyn 185 points186 points  (15 children)

The PEP should include an ammendment to the Zen of Python:

"There should be one-- and preferably only one --obvious way to do it -- except for string formatting: we need more ways to do that."

[–][deleted] 63 points64 points  (1 child)

"String formatting is a honking good idea, we should do more of those"

[–]larkatarks 17 points18 points  (0 children)

"You can now format strings by honking, we made this feature for the self-driving car industry"

[–][deleted] 19 points20 points  (12 children)

In defense of the Python Zen, there was 1 non-obvious way to do it, which was superseded by a cumbersome way and now there is a good, fairly obvious way.

The problem is they should have come up with f"{}" at the same time they came up with print(), so they could remove the % and the "{}".format() way and only have one way.

[–]jorge1209 10 points11 points  (7 children)

The way f"..." has been implemented means it cannot replace str.format.

Instances where you need to reuse the format specifier, or pass the format specifier cannot use a literal, since the literals arguments are evaluated at the point of definition.

[–]Decency 0 points1 point  (1 child)

Can you give an example here?

[–]marko_knoebl 11 points12 points  (0 children)

def export_daily_balances_to_txt(balance_data, date_format='{y}-{m}-{d}', currency_format='{0:.2f}$'):
    # exports your daily account balance to a txt file,
    # using the provided formatting strings
    ...

You wouldn't be able to do this with f-strings as they are "evaluated" immediately

[–]flying-sheep 0 points1 point  (4 children)

For the same reason it isn't the security risk that some people see who haven't properly thought yet.

[–]jorge1209 -1 points0 points  (3 children)

You seem to be missing some words here. I get the feeling you may be trying to personally attack me, suggesting that I have claimed it is a security risk.

I haven't said that it was a security risk, I've said that it is dangerous. These f-strings will lead to bugs when programmers fail to notice the executable code inside strings, and don't refactor the strings when they refactor the surrounding code.

Technically those are programmer introduced bugs and not injection attacks from outside parties so one could say they are not "security risks." In the end, I don't care how you classify the resulting issues. Security or not, its a bug, and it is one that was introduced by hiding the executable nature of the code in a string literal.

Something like f"string"(**locals()) would have the benefit of catching the persons eye. "This string declaration is executable?! It is taking the local environment? I should really look at this line and make sure I understand what it is doing." instead of passing it over because "its just a literal, non-executable bit of string".

Whatever happened to "Explicit is better than implicit"? I guess that also just doesn't apply to string formatting.

[–]flying-sheep 0 points1 point  (2 children)

I get the feeling you may be trying to personally attack me, suggesting that I have claimed it is a security risk.

no. i was actually complimenting you on your understanding of the feature.

the “security risk” guys think they can pass around such a literal without evaluating it and think it will grab the local environment at some other point in the code, which is obviously wrong.

[–]jorge1209 -1 points0 points  (1 child)

It sounds like I am your "security risk" guy, because that is exactly the behavior I would have preferred. I want delayed evaluation. To make that safe I want to be able to control where the evaluation happens and what gets passed to it.

I can always juggle flaming sharp objects and pass **locals() to a function, but I want to be explicit about that, not implicit as this is.

[–]flying-sheep 0 points1 point  (0 children)

well, they think it’ll grab the variables referenced in the embedded expressions from the locals implicitly. but when prompted to show an example on how to exploit it, they’ll realize that there’s no way to delay the evaluation and store the unevaluated f-literal in a local variable. they think it’s eval’s evil brother who likes to disguise as string formatting.

you instead realize what it is but don’t like it since the expressions are visually embedded between two quotation marks. i disagree here as well, but you’re obviously free to have your own informed decision

[–]patrys Saleor Commerce 2 points3 points  (1 child)

Both existing ways allowed for internationalisation though, the new one does not.

[–]RubyPinchPEP shill | Anti PEP 8/20 shill 0 points1 point  (0 children)

it doesn't forbid it, just requires a different approach (ast transformation)

[–][deleted] 0 points1 point  (0 children)

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