Skip to content

Use ExprFString for StringLike::FString variant#10311

Merged
dhruvmanila merged 4 commits intomainfrom
dhruv/string-like-f-string
Mar 14, 2024
Merged

Use ExprFString for StringLike::FString variant#10311
dhruvmanila merged 4 commits intomainfrom
dhruv/string-like-f-string

Conversation

@dhruvmanila
Copy link
Member

@dhruvmanila dhruvmanila commented Mar 9, 2024

Summary

This PR updates the StringLike::FString variant to use ExprFString instead of FStringLiteralElement.

For context, the reason it used FStringLiteralElement is that the node is actually the string part of an f-string ("foo" in f"foo{x}"). But, this is inconsistent with other variants where the captured value is the entire string.

This is also problematic w.r.t. implicitly concatenated strings. Any rules which work with StringLike::FString doesn't account for the string part in an implicitly concatenated f-strings. For example, we don't flag confusable character in the first part of "𝐁ad" f"𝐁ad string", but only the second part (https://play.ruff.rs/16071c4c-a1dd-4920-b56f-e2ce2f69c843).

Update PYI053

This is included in this PR because otherwise it requires a temporary workaround to be compatible with the old logic.

This PR also updates the PYI053 (string-or-bytes-too-long) rule for f-string to consider all the visible characters in a f-string, including the ones which are implicitly concatenated. This is consistent with implicitly concatenated strings and bytes.

For example,

def foo(
	# We count all the characters here
    arg1: str = '51 character ' 'stringgggggggggggggggggggggggggggggggg',
	# But not here because of the `{x}` replacement field which _breaks_ them up into two chunks
    arg2: str = f'51 character {x} stringgggggggggggggggggggggggggggggggggggggggggggg',
) -> None: ...

This PR fixes it to consider all visible characters inside an f-string which includes expressions as well.

fixes: #10310
fixes: #10307

Test Plan

Add new test cases and update the snapshots.

Review

To facilitate the review process, the change have been split into two commits: one which has the code change while the other has the test cases and updated snapshots.

@github-actions
Copy link
Contributor

github-actions bot commented Mar 9, 2024

ruff-ecosystem results

Linter (stable)

✅ ecosystem check detected no linter changes.

Linter (preview)

✅ ecosystem check detected no linter changes.

Formatter (stable)

✅ ecosystem check detected no format changes.

Formatter (preview)

✅ ecosystem check detected no format changes.

@dhruvmanila dhruvmanila force-pushed the dhruv/string-like-f-string branch from dad0e35 to ab4b600 Compare March 9, 2024 12:06
Comment on lines +23 to +24
# Implicit string concatenation
"0.0.0.0" f"0.0.0.0{expr}0.0.0.0"
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not exactly correct (#10308) but for now it's fine.

Comment on lines +49 to +71
StringLike::FString(ast::ExprFString { value, .. }) => {
for part in value {
match part {
ast::FStringPart::Literal(literal) => {
if &**literal == "0.0.0.0" {
checker
.diagnostics
.push(Diagnostic::new(HardcodedBindAllInterfaces, literal.range()));
}
}
ast::FStringPart::FString(f_string) => {
for literal in f_string.literals() {
if &**literal == "0.0.0.0" {
checker.diagnostics.push(Diagnostic::new(
HardcodedBindAllInterfaces,
literal.range(),
));
}
}
}
}
}
}
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This logic is being repeated for all three rules changed in this PR. The logic being:

  • Loop over each f-string part
    • If it's a string literal, then directly run the check on it
    • If it's an f-string, loop over each literal and expression element of it

I'm not exactly sure on how to avoid duplicating this logic or if it's possible without introducing additional complexity.

Base automatically changed from dhruv/f-string-iters to main March 13, 2024 08:46
@dhruvmanila dhruvmanila force-pushed the dhruv/string-like-f-string branch from ab4b600 to 67810b6 Compare March 13, 2024 08:51
@dhruvmanila dhruvmanila force-pushed the dhruv/string-like-f-string branch from 67810b6 to 1ef5e95 Compare March 14, 2024 07:43
Copy link
Member

@AlexWaygood AlexWaygood left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the flake8-pyi changes LGTM now, thanks!

@dhruvmanila dhruvmanila added the internal An internal refactor or improvement label Mar 14, 2024
@dhruvmanila dhruvmanila merged commit 5f40371 into main Mar 14, 2024
@dhruvmanila dhruvmanila deleted the dhruv/string-like-f-string branch March 14, 2024 08:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

internal An internal refactor or improvement

Projects

None yet

Development

Successfully merging this pull request may close these issues.

RUF001 isn't highlighted for implicitly concatenated f-string Invalid fix for PYI053 for f-strings

3 participants