diff --git a/crates/ruff_linter/resources/test/fixtures/ruff/RUF100_3.py b/crates/ruff_linter/resources/test/fixtures/ruff/RUF100_3.py index 17e6367ad0592..2269552c3be14 100644 --- a/crates/ruff_linter/resources/test/fixtures/ruff/RUF100_3.py +++ b/crates/ruff_linter/resources/test/fixtures/ruff/RUF100_3.py @@ -23,6 +23,9 @@ print(a) # noqa: E501, F821 # comment print(a) # noqa: E501, F821 comment print(a) # noqa: E501, F821 comment +print(a) # noqa: E501,,F821 comment +print(a) # noqa: E501, ,F821 comment +print(a) # noqa: E501 F821 comment print(a) # comment with unicode µ # noqa: E501 print(a) # comment with unicode µ # noqa: E501, F821 diff --git a/crates/ruff_linter/src/noqa.rs b/crates/ruff_linter/src/noqa.rs index 948cd534f95da..f734448c795e2 100644 --- a/crates/ruff_linter/src/noqa.rs +++ b/crates/ruff_linter/src/noqa.rs @@ -183,7 +183,7 @@ impl<'a> Directive<'a> { // Extract, e.g., the `401` in `F401`. let suffix = line[prefix..] .chars() - .take_while(char::is_ascii_digit) + .take_while(char::is_ascii_alphanumeric) .count(); if prefix > 0 && suffix > 0 { Some(&line[..prefix + suffix]) @@ -549,7 +549,7 @@ impl<'a> ParsedFileExemption<'a> { // Extract, e.g., the `401` in `F401`. let suffix = line[prefix..] .chars() - .take_while(char::is_ascii_digit) + .take_while(char::is_ascii_alphanumeric) .count(); if prefix > 0 && suffix > 0 { Some(&line[..prefix + suffix]) @@ -895,7 +895,7 @@ pub(crate) struct NoqaDirectiveLine<'a> { pub(crate) directive: Directive<'a>, /// The codes that are ignored by the directive. pub(crate) matches: Vec, - // Whether the directive applies to range.end + /// Whether the directive applies to `range.end`. pub(crate) includes_end: bool, } @@ -1191,6 +1191,24 @@ mod tests { assert_debug_snapshot!(Directive::try_extract(source, TextSize::default())); } + #[test] + fn noqa_squashed_codes() { + let source = "# noqa: F401F841"; + assert_debug_snapshot!(Directive::try_extract(source, TextSize::default())); + } + + #[test] + fn noqa_empty_comma() { + let source = "# noqa: F401,,F841"; + assert_debug_snapshot!(Directive::try_extract(source, TextSize::default())); + } + + #[test] + fn noqa_empty_comma_space() { + let source = "# noqa: F401, ,F841"; + assert_debug_snapshot!(Directive::try_extract(source, TextSize::default())); + } + #[test] fn noqa_invalid_suffix() { let source = "# noqa[F401]"; diff --git a/crates/ruff_linter/src/rules/ruff/snapshots/ruff_linter__rules__ruff__tests__ruf100_3.snap b/crates/ruff_linter/src/rules/ruff/snapshots/ruff_linter__rules__ruff__tests__ruf100_3.snap index 1ccfc73987d4e..187117c3e0e80 100644 --- a/crates/ruff_linter/src/rules/ruff/snapshots/ruff_linter__rules__ruff__tests__ruf100_3.snap +++ b/crates/ruff_linter/src/rules/ruff/snapshots/ruff_linter__rules__ruff__tests__ruf100_3.snap @@ -344,7 +344,7 @@ RUF100_3.py:23:11: RUF100 [*] Unused `noqa` directive (unused: `E501`) 23 |+print(a) # noqa: F821 # comment 24 24 | print(a) # noqa: E501, F821 comment 25 25 | print(a) # noqa: E501, F821 comment -26 26 | +26 26 | print(a) # noqa: E501,,F821 comment RUF100_3.py:24:11: RUF100 [*] Unused `noqa` directive (unused: `E501`) | @@ -353,6 +353,7 @@ RUF100_3.py:24:11: RUF100 [*] Unused `noqa` directive (unused: `E501`) 24 | print(a) # noqa: E501, F821 comment | ^^^^^^^^^^^^^^^^^^ RUF100 25 | print(a) # noqa: E501, F821 comment +26 | print(a) # noqa: E501,,F821 comment | = help: Remove unused `noqa` directive @@ -363,8 +364,8 @@ RUF100_3.py:24:11: RUF100 [*] Unused `noqa` directive (unused: `E501`) 24 |-print(a) # noqa: E501, F821 comment 24 |+print(a) # noqa: F821 comment 25 25 | print(a) # noqa: E501, F821 comment -26 26 | -27 27 | print(a) # comment with unicode µ # noqa: E501 +26 26 | print(a) # noqa: E501,,F821 comment +27 27 | print(a) # noqa: E501, ,F821 comment RUF100_3.py:25:11: RUF100 [*] Unused `noqa` directive (unused: `E501`) | @@ -372,8 +373,8 @@ RUF100_3.py:25:11: RUF100 [*] Unused `noqa` directive (unused: `E501`) 24 | print(a) # noqa: E501, F821 comment 25 | print(a) # noqa: E501, F821 comment | ^^^^^^^^^^^^^^^^^^ RUF100 -26 | -27 | print(a) # comment with unicode µ # noqa: E501 +26 | print(a) # noqa: E501,,F821 comment +27 | print(a) # noqa: E501, ,F821 comment | = help: Remove unused `noqa` directive @@ -383,48 +384,110 @@ RUF100_3.py:25:11: RUF100 [*] Unused `noqa` directive (unused: `E501`) 24 24 | print(a) # noqa: E501, F821 comment 25 |-print(a) # noqa: E501, F821 comment 25 |+print(a) # noqa: F821 comment -26 26 | -27 27 | print(a) # comment with unicode µ # noqa: E501 -28 28 | print(a) # comment with unicode µ # noqa: E501, F821 +26 26 | print(a) # noqa: E501,,F821 comment +27 27 | print(a) # noqa: E501, ,F821 comment +28 28 | print(a) # noqa: E501 F821 comment -RUF100_3.py:27:7: F821 Undefined name `a` +RUF100_3.py:26:11: RUF100 [*] Unused `noqa` directive (unused: `E501`) | +24 | print(a) # noqa: E501, F821 comment 25 | print(a) # noqa: E501, F821 comment -26 | -27 | print(a) # comment with unicode µ # noqa: E501 - | ^ F821 -28 | print(a) # comment with unicode µ # noqa: E501, F821 +26 | print(a) # noqa: E501,,F821 comment + | ^^^^^^^^^^^^^^^^^^ RUF100 +27 | print(a) # noqa: E501, ,F821 comment +28 | print(a) # noqa: E501 F821 comment | + = help: Remove unused `noqa` directive -RUF100_3.py:27:39: RUF100 [*] Unused `noqa` directive (unused: `E501`) +ℹ Safe fix +23 23 | print(a) # noqa: E501, F821 # comment +24 24 | print(a) # noqa: E501, F821 comment +25 25 | print(a) # noqa: E501, F821 comment +26 |-print(a) # noqa: E501,,F821 comment + 26 |+print(a) # noqa: F821 comment +27 27 | print(a) # noqa: E501, ,F821 comment +28 28 | print(a) # noqa: E501 F821 comment +29 29 | + +RUF100_3.py:27:11: RUF100 [*] Unused `noqa` directive (unused: `E501`) | 25 | print(a) # noqa: E501, F821 comment -26 | -27 | print(a) # comment with unicode µ # noqa: E501 - | ^^^^^^^^^^^^ RUF100 -28 | print(a) # comment with unicode µ # noqa: E501, F821 +26 | print(a) # noqa: E501,,F821 comment +27 | print(a) # noqa: E501, ,F821 comment + | ^^^^^^^^^^^^^^^^^^^ RUF100 +28 | print(a) # noqa: E501 F821 comment | = help: Remove unused `noqa` directive ℹ Safe fix 24 24 | print(a) # noqa: E501, F821 comment 25 25 | print(a) # noqa: E501, F821 comment -26 26 | -27 |-print(a) # comment with unicode µ # noqa: E501 - 27 |+print(a) # comment with unicode µ -28 28 | print(a) # comment with unicode µ # noqa: E501, F821 +26 26 | print(a) # noqa: E501,,F821 comment +27 |-print(a) # noqa: E501, ,F821 comment + 27 |+print(a) # noqa: F821 comment +28 28 | print(a) # noqa: E501 F821 comment +29 29 | +30 30 | print(a) # comment with unicode µ # noqa: E501 + +RUF100_3.py:28:11: RUF100 [*] Unused `noqa` directive (unused: `E501`) + | +26 | print(a) # noqa: E501,,F821 comment +27 | print(a) # noqa: E501, ,F821 comment +28 | print(a) # noqa: E501 F821 comment + | ^^^^^^^^^^^^^^^^^ RUF100 +29 | +30 | print(a) # comment with unicode µ # noqa: E501 + | + = help: Remove unused `noqa` directive + +ℹ Safe fix +25 25 | print(a) # noqa: E501, F821 comment +26 26 | print(a) # noqa: E501,,F821 comment +27 27 | print(a) # noqa: E501, ,F821 comment +28 |-print(a) # noqa: E501 F821 comment + 28 |+print(a) # noqa: F821 comment +29 29 | +30 30 | print(a) # comment with unicode µ # noqa: E501 +31 31 | print(a) # comment with unicode µ # noqa: E501, F821 + +RUF100_3.py:30:7: F821 Undefined name `a` + | +28 | print(a) # noqa: E501 F821 comment +29 | +30 | print(a) # comment with unicode µ # noqa: E501 + | ^ F821 +31 | print(a) # comment with unicode µ # noqa: E501, F821 + | -RUF100_3.py:28:39: RUF100 [*] Unused `noqa` directive (unused: `E501`) +RUF100_3.py:30:39: RUF100 [*] Unused `noqa` directive (unused: `E501`) | -27 | print(a) # comment with unicode µ # noqa: E501 -28 | print(a) # comment with unicode µ # noqa: E501, F821 +28 | print(a) # noqa: E501 F821 comment +29 | +30 | print(a) # comment with unicode µ # noqa: E501 + | ^^^^^^^^^^^^ RUF100 +31 | print(a) # comment with unicode µ # noqa: E501, F821 + | + = help: Remove unused `noqa` directive + +ℹ Safe fix +27 27 | print(a) # noqa: E501, ,F821 comment +28 28 | print(a) # noqa: E501 F821 comment +29 29 | +30 |-print(a) # comment with unicode µ # noqa: E501 + 30 |+print(a) # comment with unicode µ +31 31 | print(a) # comment with unicode µ # noqa: E501, F821 + +RUF100_3.py:31:39: RUF100 [*] Unused `noqa` directive (unused: `E501`) + | +30 | print(a) # comment with unicode µ # noqa: E501 +31 | print(a) # comment with unicode µ # noqa: E501, F821 | ^^^^^^^^^^^^^^^^^^ RUF100 | = help: Remove unused `noqa` directive ℹ Safe fix -25 25 | print(a) # noqa: E501, F821 comment -26 26 | -27 27 | print(a) # comment with unicode µ # noqa: E501 -28 |-print(a) # comment with unicode µ # noqa: E501, F821 - 28 |+print(a) # comment with unicode µ # noqa: F821 +28 28 | print(a) # noqa: E501 F821 comment +29 29 | +30 30 | print(a) # comment with unicode µ # noqa: E501 +31 |-print(a) # comment with unicode µ # noqa: E501, F821 + 31 |+print(a) # comment with unicode µ # noqa: F821 diff --git a/crates/ruff_linter/src/snapshots/ruff_linter__noqa__tests__noqa_empty_comma.snap b/crates/ruff_linter/src/snapshots/ruff_linter__noqa__tests__noqa_empty_comma.snap new file mode 100644 index 0000000000000..7a83ed9db2271 --- /dev/null +++ b/crates/ruff_linter/src/snapshots/ruff_linter__noqa__tests__noqa_empty_comma.snap @@ -0,0 +1,23 @@ +--- +source: crates/ruff_linter/src/noqa.rs +expression: "Directive::try_extract(source, TextSize::default())" +--- +Ok( + Some( + Codes( + Codes { + range: 0..18, + codes: [ + Code { + code: "F401", + range: 8..12, + }, + Code { + code: "F841", + range: 14..18, + }, + ], + }, + ), + ), +) diff --git a/crates/ruff_linter/src/snapshots/ruff_linter__noqa__tests__noqa_empty_comma_space.snap b/crates/ruff_linter/src/snapshots/ruff_linter__noqa__tests__noqa_empty_comma_space.snap new file mode 100644 index 0000000000000..c2a215c16ff19 --- /dev/null +++ b/crates/ruff_linter/src/snapshots/ruff_linter__noqa__tests__noqa_empty_comma_space.snap @@ -0,0 +1,23 @@ +--- +source: crates/ruff_linter/src/noqa.rs +expression: "Directive::try_extract(source, TextSize::default())" +--- +Ok( + Some( + Codes( + Codes { + range: 0..19, + codes: [ + Code { + code: "F401", + range: 8..12, + }, + Code { + code: "F841", + range: 15..19, + }, + ], + }, + ), + ), +) diff --git a/crates/ruff_linter/src/snapshots/ruff_linter__noqa__tests__noqa_squashed_codes.snap b/crates/ruff_linter/src/snapshots/ruff_linter__noqa__tests__noqa_squashed_codes.snap new file mode 100644 index 0000000000000..8a6adc1cc7a11 --- /dev/null +++ b/crates/ruff_linter/src/snapshots/ruff_linter__noqa__tests__noqa_squashed_codes.snap @@ -0,0 +1,19 @@ +--- +source: crates/ruff_linter/src/noqa.rs +expression: "Directive::try_extract(source, TextSize::default())" +--- +Ok( + Some( + Codes( + Codes { + range: 0..16, + codes: [ + Code { + code: "F401F841", + range: 8..16, + }, + ], + }, + ), + ), +)