-
Notifications
You must be signed in to change notification settings - Fork 36.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
refactor: Clean up messy strformat and bilingual_str usages #31072
Conversation
The following sections might be updated with supplementary metadata relevant to reviewers and maintainers. Code Coverage & BenchmarksFor details see: https://corecheck.dev/bitcoin/bitcoin/pulls/31072. ReviewsSee the guideline for information on the review process.
If your review is incorrectly listed, please react with 👎 to this comment and the bot will ignore it on the next update. ConflictsReviewers, this pull request conflicts with the following ones:
If you consider this pull request important, please also help to review the conflicting pull requests. Ideally, start with the one that should be merged first. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't mind the changes here, but I don't think the motivation is correct and it seems verbose and misleading.
I don't think it matters much whether this is merged or not, but you could just replace the motivation with:
"This replacement makes the implementation of some compile-time checks in the future easier. Also, it makes the code a bit more consistent in that Untranslated
isn't allowed as a format-string anymore, only plain std::string
s, or translated strings. The downside would be that developers may have to use operator+
more often, making it a bit harder to write code involving formatting of (un)translated strings. However, if it becomes too annoying, the changes here should be easy to revert."
Updated 9a101d2 -> 022ffd1 ( re: #31072 (review)
I don't know what was misleading, but I rewrote description and will paste old text in comment below in case it's useful. Sorry for verbosity, I like to think by writing, but it doesn't always result in the most helpful thing to read. Original PR description
scripted-diff: Replace strprintf(Untranslated(...)) with Untranslated(strprintf(...)) This PR is just a scripted-diff replacing strprintf calls like: strprintf(Untranslated("Error parsing command line arguments: %s"), error)) with: Untranslated(strprintf("Error parsing command line arguments: %s", error)) Currently code is inconsistent and uses a mix of both styles, but second style is better because:
One potential downside of this change, pointed out #31061 (comment), is that after this PR if you want to change an untranslated format string to a translated one (or vice versa), you will have to to add An alternative to this PR could be a scripted-diff switching all code to use Note: The scripted diff in this PR only removes current |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm. Left some comments for context.
@@ -6091,7 +6091,7 @@ SnapshotCompletionResult ChainstateManager::MaybeCompleteSnapshotValidation() | |||
|
|||
auto rename_result = m_snapshot_chainstate->InvalidateCoinsDBOnDisk(); | |||
if (!rename_result) { | |||
user_error = strprintf(Untranslated("%s\n%s"), user_error, util::ErrorString(rename_result)); | |||
user_error += Untranslated("\n") + util::ErrorString(rename_result); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fdd1992: I am thinking that strprintf(Untranslated("something"), ...)
is something that may be used normally. Right now, it may not be used extensively, or only used to concatenate two blobs. However, I can imagine that in the future someone may want to write strprintf(Untranslated("<a href="...">%s</a><br>%s<br>"), ...)
to format some bilingual strings into html, which would be a bit more verbose by doing with plenty of +
.
Not saying that this is something common, but I wanted to mention it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
re: #31072 (comment)
Thanks, we also talked about this offline and I agree that strprintf can often be nicer than concatenation for building strings, but I think this approach doesn't work very well for untranslated bilingual strings. For example in the HTML case, you would probably only want to format the translated strings as HTML, not both translated and original strings. I think the downsides of supporting untranslated format strings outweigh the upsides. (Downsides being having two inconsistent ways of formatting the same strings, having a more complicated interface, and potential for introducing mixed translation bugs.)
Concept ACK. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@@ -6091,7 +6091,7 @@ SnapshotCompletionResult ChainstateManager::MaybeCompleteSnapshotValidation() | |||
|
|||
auto rename_result = m_snapshot_chainstate->InvalidateCoinsDBOnDisk(); | |||
if (!rename_result) { | |||
user_error = strprintf(Untranslated("%s\n%s"), user_error, util::ErrorString(rename_result)); | |||
user_error += Untranslated("\n") + util::ErrorString(rename_result); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
re: #31072 (comment)
Thanks, we also talked about this offline and I agree that strprintf can often be nicer than concatenation for building strings, but I think this approach doesn't work very well for untranslated bilingual strings. For example in the HTML case, you would probably only want to format the translated strings as HTML, not both translated and original strings. I think the downsides of supporting untranslated format strings outweigh the upsides. (Downsides being having two inconsistent ways of formatting the same strings, having a more complicated interface, and potential for introducing mixed translation bugs.)
…t strings fe39acf tinyformat: Add compile-time checking for literal format strings (Ryan Ofsky) 184f34f util: Support dynamic width & precision in ConstevalFormatString (Ryan Ofsky) Pull request description: Add compile-time checking for literal format strings passed to `strprintf` and `tfm::format` to make sure the right number of format arguments are passed. There is still no compile-time checking if non-literal `std::string` or `bilingual_str` format strings are passed, but this is improved in other PRs: - [#31061](#31061) implements compile-time checking for translated strings - [#31072](#31072) increases compile-time checking by using literal strings as format strings, instead of `std::string` and `bilingual_str` - [#31149](#31149) may drop the `std::string` overload for `strprintf` to [require](#31149 (comment)) compile-time checking ACKs for top commit: maflcko: re-ACK fe39acf 🕐 l0rinc: ACK fe39acf hodlinator: re-ACK fe39acf Tree-SHA512: f1ddef0c96b9468c5ffe31b42dc19f1922583dd14f2e180b618d992c98614c5cc7db9f9cd917ef503f833bbc7dbec78e4489d0035416dce6840837e1d66d87cb
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ACK 85df2fb
I have basically redone the change locally to understand it better and mostly left questions or nits, I'm fine with merging as is
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ACK 3b24c24 |
Instead just concatenate already formatted strings. This allows untranslated format strings to be checked at compile time now, and translated format strings to be checked at compile time in bitcoin#31061.
This could produce an english error message containing non-english string fragments if PopulateAndValidateSnapshot started returning any translated strings in the future. This change is also needed to make the next scripted-diff commit work.
…anslated strings This change manually removes two strprintf(Untranslated...) calls. All remaining calls are removed in the next scripted-diff commit. Removing these calls makes code more consistent and makes it easier to implement compile-time checking enforcing that format strings contain valid specifiers, by avoiding the need for the Untranslated() function to be involved in formatting. Additionally, using + and += instead of strprintf here makes code a little shorter, and more type-safe because + unlike strprintf only works on strings of the same type, making it less likely english strings and bilingual strings will be unintentionally combined.
…rintf) This makes code more consistent and makes it easier to add compile-time checking to enforce that format strings contain the right specifiers, because it stops using Untranslated() to create the format string, so the Untranslated() function will not need to get involved in formatting. -BEGIN VERIFY SCRIPT- quote='"[^"]+"' quotes="(?:$quote|\\s)*" nonparens="[^()]*" single_level_paren="\($nonparens\)" double_level_paren="\($nonparens\($nonparens\)$nonparens\)" exprs="(?:$double_level_paren|$single_level_paren|$nonparens)*" git grep -l 'Untranslated' | xargs perl -0777 -i -pe "s/strprintf\((\\W*)Untranslated\(($quotes)\)($exprs)(\))/Untranslated(\1strprintf(\2\3))/gs" -END VERIFY SCRIPT-
lgtm ACK 0184d33 🔹 Show signatureSignature:
|
ACK 0184d33 - no overall difference because of the rebase |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
post-merge-ACK
Really cleaned the slate nicely for #31061.
errors.push_back(strprintf( | ||
Untranslated("New fee rate (%s) is lower than the minimum fee rate (%s) to get into the mempool -- "), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A bit curious about why the caliber of the scripted diff was so powerful, but I guess this multi-line case is it. Would also catch potential other cases like it which could have been merged between the parent commit of this PR and when it ended up being merged.
This PR cleans up string formatting in the codebase so other PRs adding compile time checking can be simpler and easier to review (specifically #30928, #31061, #31074, and #31149).
Currently these PRs are hard to review because in addition to changing formatting APIs, they have to update callers that are using the API's in unusual ways. Clean up these callers now so later PRs can be simpler. Specifically:
std::string
format strings to enable more compile-time checking.Untranslated(strprintf(...))
overstrprintf(Untranslated(...), ...)
for consistency and to prevent translated and untranslated strings from being unintentionally combined.