From cb469be2f5f01ff1b978ea74ddcae23d092b675e Mon Sep 17 00:00:00 2001 From: Frederick Stempfle Date: Mon, 23 Feb 2026 17:24:18 +0100 Subject: [PATCH] Suppress RUF027 fix for f-strings with comments targeting Python < 3.12 --- .../resources/test/fixtures/ruff/RUF027_0.py | 8 +++ .../ruff/rules/missing_fstring_syntax.rs | 9 ++-- ...ules__ruff__tests__RUF027_RUF027_0.py.snap | 24 +++++++++ ...issing_fstring_syntax_backslash_py311.snap | 50 ++++++++++++++++++- 4 files changed, 87 insertions(+), 4 deletions(-) diff --git a/crates/ruff_linter/resources/test/fixtures/ruff/RUF027_0.py b/crates/ruff_linter/resources/test/fixtures/ruff/RUF027_0.py index 04c482bd5226e..8088d6991ba09 100644 --- a/crates/ruff_linter/resources/test/fixtures/ruff/RUF027_0.py +++ b/crates/ruff_linter/resources/test/fixtures/ruff/RUF027_0.py @@ -90,3 +90,11 @@ def fuzz_bug(): def backslash_test(): x = "test" print("Hello {'\\n'}{x}") # Should not trigger RUF027 for Python < 3.12 + +# Test case for comment handling in f-string interpolations +# Should not trigger RUF027 for Python < 3.12 due to comments in interpolations +# https://github.com/astral-sh/ruff/issues/23460 +def comment_test(): + x = "!" + print("""{x # } +}""") diff --git a/crates/ruff_linter/src/rules/ruff/rules/missing_fstring_syntax.rs b/crates/ruff_linter/src/rules/ruff/rules/missing_fstring_syntax.rs index df64e8532bc85..d4ad5d475ec94 100644 --- a/crates/ruff_linter/src/rules/ruff/rules/missing_fstring_syntax.rs +++ b/crates/ruff_linter/src/rules/ruff/rules/missing_fstring_syntax.rs @@ -226,10 +226,13 @@ fn should_be_fstring( for f_string in value.f_strings() { let mut has_name = false; for element in f_string.elements.interpolations() { - // Check if the interpolation expression contains backslashes - // F-strings with backslashes in interpolations are only valid in Python 3.12+ + // F-strings with backslashes or comments in interpolations are only + // valid in Python 3.12+ (PEP 701) let interpolation_text = &fstring_expr[element.range()]; - if target_version < PythonVersion::PY312 && interpolation_text.contains('\\') { + if target_version < PythonVersion::PY312 + && (interpolation_text.contains('\\') + || interpolation_text.contains('#')) + { return false; } diff --git a/crates/ruff_linter/src/rules/ruff/snapshots/ruff_linter__rules__ruff__tests__RUF027_RUF027_0.py.snap b/crates/ruff_linter/src/rules/ruff/snapshots/ruff_linter__rules__ruff__tests__RUF027_RUF027_0.py.snap index 977628639da71..75a92d7da9375 100644 --- a/crates/ruff_linter/src/rules/ruff/snapshots/ruff_linter__rules__ruff__tests__RUF027_RUF027_0.py.snap +++ b/crates/ruff_linter/src/rules/ruff/snapshots/ruff_linter__rules__ruff__tests__RUF027_RUF027_0.py.snap @@ -328,6 +328,8 @@ RUF027 [*] Possible f-string without an `f` prefix 91 | x = "test" 92 | print("Hello {'\\n'}{x}") # Should not trigger RUF027 for Python < 3.12 | ^^^^^^^^^^^^^^^^^^ +93 | +94 | # Test case for comment handling in f-string interpolations | help: Add `f` prefix 89 | # Should not trigger RUF027 for Python < 3.12 due to backslashes in interpolations @@ -335,4 +337,26 @@ help: Add `f` prefix 91 | x = "test" - print("Hello {'\\n'}{x}") # Should not trigger RUF027 for Python < 3.12 92 + print(f"Hello {'\\n'}{x}") # Should not trigger RUF027 for Python < 3.12 +93 | +94 | # Test case for comment handling in f-string interpolations +95 | # Should not trigger RUF027 for Python < 3.12 due to comments in interpolations +note: This is an unsafe fix and may change runtime behavior + +RUF027 [*] Possible f-string without an `f` prefix + --> RUF027_0.py:99:11 + | + 97 | def comment_test(): + 98 | x = "!" + 99 | print("""{x # } + | ___________^ +100 | | }""") + | |____^ + | +help: Add `f` prefix +96 | # https://github.com/astral-sh/ruff/issues/23460 +97 | def comment_test(): +98 | x = "!" + - print("""{x # } +99 + print(f"""{x # } +100 | }""") note: This is an unsafe fix and may change runtime behavior diff --git a/crates/ruff_linter/src/rules/ruff/snapshots/ruff_linter__rules__ruff__tests__missing_fstring_syntax_backslash_py311.snap b/crates/ruff_linter/src/rules/ruff/snapshots/ruff_linter__rules__ruff__tests__missing_fstring_syntax_backslash_py311.snap index 8e6692f7a5628..a1373cf7adc6e 100644 --- a/crates/ruff_linter/src/rules/ruff/snapshots/ruff_linter__rules__ruff__tests__missing_fstring_syntax_backslash_py311.snap +++ b/crates/ruff_linter/src/rules/ruff/snapshots/ruff_linter__rules__ruff__tests__missing_fstring_syntax_backslash_py311.snap @@ -6,10 +6,33 @@ source: crates/ruff_linter/src/rules/ruff/mod.rs +linter.unresolved_target_version = 3.11 --- Summary --- -Removed: 2 +Removed: 4 Added: 0 --- Removed --- +RUF027 [*] Possible f-string without an `f` prefix + --> RUF027_0.py:41:22 + | +39 | single_line = """ {a} """ # RUF027 +40 | # RUF027 +41 | multi_line = a = """b { # comment + | ______________________^ +42 | | c} d +43 | | """ + | |_______^ + | +help: Add `f` prefix +38 | c = a +39 | single_line = """ {a} """ # RUF027 +40 | # RUF027 + - multi_line = a = """b { # comment +41 + multi_line = a = f"""b { # comment +42 | c} d +43 | """ +44 | +note: This is an unsafe fix and may change runtime behavior + + RUF027 [*] Possible f-string without an `f` prefix --> RUF027_0.py:49:9 | @@ -40,6 +63,8 @@ RUF027 [*] Possible f-string without an `f` prefix 91 | x = "test" 92 | print("Hello {'\\n'}{x}") # Should not trigger RUF027 for Python < 3.12 | ^^^^^^^^^^^^^^^^^^ +93 | +94 | # Test case for comment handling in f-string interpolations | help: Add `f` prefix 89 | # Should not trigger RUF027 for Python < 3.12 due to backslashes in interpolations @@ -47,4 +72,27 @@ help: Add `f` prefix 91 | x = "test" - print("Hello {'\\n'}{x}") # Should not trigger RUF027 for Python < 3.12 92 + print(f"Hello {'\\n'}{x}") # Should not trigger RUF027 for Python < 3.12 +93 | +94 | # Test case for comment handling in f-string interpolations +95 | # Should not trigger RUF027 for Python < 3.12 due to comments in interpolations +note: This is an unsafe fix and may change runtime behavior + + +RUF027 [*] Possible f-string without an `f` prefix + --> RUF027_0.py:99:11 + | + 97 | def comment_test(): + 98 | x = "!" + 99 | print("""{x # } + | ___________^ +100 | | }""") + | |____^ + | +help: Add `f` prefix +96 | # https://github.com/astral-sh/ruff/issues/23460 +97 | def comment_test(): +98 | x = "!" + - print("""{x # } +99 + print(f"""{x # } +100 | }""") note: This is an unsafe fix and may change runtime behavior