Skip to content
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

Autofix for UP032 swallows comment #6336

Closed
WhyNotHugo opened this issue Aug 4, 2023 · 7 comments · Fixed by #6342
Closed

Autofix for UP032 swallows comment #6336

WhyNotHugo opened this issue Aug 4, 2023 · 7 comments · Fixed by #6342
Labels
fixes Related to suggested fixes for violations needs-decision Awaiting a decision from a maintainer

Comments

@WhyNotHugo
Copy link
Contributor

Given this snippet:

        return "data:image/{};base64,{}".format(
            ext[1:], data.decode()  # Remove the leading dot.
        )

Ruff autofix produces this output:

        return f"data:image/{ext[1:]};base64,{data.decode()}"

Note that the autofixed code "swallows" the comment. See here for original context: WhyNotHugo/django-afip@2974184

This is reproducible with ruff 0.0.281. The relevant pyproject.toml is here.

@harupy
Copy link
Contributor

harupy commented Aug 4, 2023

@charliermarsh Can I work on fixing this?

@charliermarsh
Copy link
Member

Sure. How are you thinking of resolving? What's the expected behavior here?

@charliermarsh charliermarsh added fixes Related to suggested fixes for violations needs-decision Awaiting a decision from a maintainer labels Aug 4, 2023
@harupy
Copy link
Contributor

harupy commented Aug 4, 2023

diff --git a/crates/ruff/src/rules/pyupgrade/rules/f_strings.rs b/crates/ruff/src/rules/pyupgrade/rules/f_strings.rs
index 1739207cb..2dbf10061 100644
--- a/crates/ruff/src/rules/pyupgrade/rules/f_strings.rs
+++ b/crates/ruff/src/rules/pyupgrade/rules/f_strings.rs
@@ -320,7 +320,7 @@ pub(crate) fn f_strings(
         return;
     };
 
-    let Expr::Attribute(ast::ExprAttribute { value, .. }) = func.as_ref() else {
+    let Expr::Attribute(ast::ExprAttribute { value, attr, .. }) = func.as_ref() else {
         return;
     };
 
@@ -334,6 +334,25 @@ pub(crate) fn f_strings(
         return;
     };
 
+    // Exit if comments are present in the argument range:
+    // ```
+    // "{} {}".format(
+    //   1,  # 1
+    //   2,  # 2
+    // )
+    // ```
+    if lexer::lex(
+        checker
+            .locator()
+            .slice(TextRange::new(attr.start(), expr.end())),
+        Mode::Expression,
+    )
+    .flatten()
+    .any(|(tok, _)| matches!(tok, Tok::Comment(..)))
+    {
+        return;
+    }
+
     let Some(mut summary) = FormatSummaryValues::try_from_expr(expr, checker.locator()) else {
         return;
     };

I think preserving comments is not easy. Can we avoid raising UP032 if comments are present in the argument range like this^?

@WhyNotHugo
Copy link
Contributor Author

Can we avoid raising UP032 if comments are present in the argument range like this^?

That's definitely one approach. Another possible approach is to raise the warning but skip it when auto-fixing.

I'll let you decide which one is best :)

@charliermarsh
Copy link
Member

Yeah I'd say raise-but-not-fix if there are comments within the call.

@harupy
Copy link
Contributor

harupy commented Aug 4, 2023

+1 to raise-but-not-fix.

@WhyNotHugo
Copy link
Contributor Author

WhyNotHugo commented Aug 4, 2023 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
fixes Related to suggested fixes for violations needs-decision Awaiting a decision from a maintainer
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants