Avoid off-by-one error in stripping noqa following multi-byte char (#8979)

Closes https://github.com/astral-sh/ruff/issues/8976.
This commit is contained in:
Charlie Marsh 2023-12-03 11:01:58 -05:00 committed by GitHub
parent 1dda669f9a
commit 17c8817695
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 57 additions and 10 deletions

View file

@ -23,3 +23,6 @@ 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) # noqa: E501, F821 comment
print(a) # comment with unicode µ # noqa: E501
print(a) # comment with unicode µ # noqa: E501, F821

View file

@ -3,10 +3,10 @@
use std::path::Path; use std::path::Path;
use itertools::Itertools; use itertools::Itertools;
use ruff_text_size::{Ranged, TextLen, TextRange, TextSize}; use ruff_text_size::{Ranged, TextLen, TextRange};
use ruff_diagnostics::{Diagnostic, Edit, Fix}; use ruff_diagnostics::{Diagnostic, Edit, Fix};
use ruff_python_trivia::CommentRanges; use ruff_python_trivia::{CommentRanges, PythonWhitespace};
use ruff_source_file::Locator; use ruff_source_file::Locator;
use crate::noqa; use crate::noqa;
@ -200,17 +200,11 @@ fn delete_noqa(range: TextRange, locator: &Locator) -> Edit {
// Compute the leading space. // Compute the leading space.
let prefix = locator.slice(TextRange::new(line_range.start(), range.start())); let prefix = locator.slice(TextRange::new(line_range.start(), range.start()));
let leading_space = prefix let leading_space_len = prefix.text_len() - prefix.trim_whitespace_end().text_len();
.rfind(|c: char| !c.is_whitespace())
.map_or(prefix.len(), |i| prefix.len() - i - 1);
let leading_space_len = TextSize::try_from(leading_space).unwrap();
// Compute the trailing space. // Compute the trailing space.
let suffix = locator.slice(TextRange::new(range.end(), line_range.end())); let suffix = locator.slice(TextRange::new(range.end(), line_range.end()));
let trailing_space = suffix let trailing_space_len = suffix.text_len() - suffix.trim_whitespace_start().text_len();
.find(|c: char| !c.is_whitespace())
.map_or(suffix.len(), |i| i);
let trailing_space_len = TextSize::try_from(trailing_space).unwrap();
// Ex) `# noqa` // Ex) `# noqa`
if line_range if line_range

View file

@ -344,6 +344,7 @@ RUF100_3.py:23:11: RUF100 [*] Unused `noqa` directive (unused: `E501`)
23 |+print(a) # noqa: F821 # comment 23 |+print(a) # noqa: F821 # comment
24 24 | print(a) # noqa: E501, F821 comment 24 24 | print(a) # noqa: E501, F821 comment
25 25 | print(a) # noqa: E501, F821 comment 25 25 | print(a) # noqa: E501, F821 comment
26 26 |
RUF100_3.py:24:11: RUF100 [*] Unused `noqa` directive (unused: `E501`) RUF100_3.py:24:11: RUF100 [*] Unused `noqa` directive (unused: `E501`)
| |
@ -362,6 +363,8 @@ RUF100_3.py:24:11: RUF100 [*] Unused `noqa` directive (unused: `E501`)
24 |-print(a) # noqa: E501, F821 comment 24 |-print(a) # noqa: E501, F821 comment
24 |+print(a) # noqa: F821 comment 24 |+print(a) # noqa: F821 comment
25 25 | print(a) # noqa: E501, F821 comment 25 25 | print(a) # noqa: E501, F821 comment
26 26 |
27 27 | print(a) # comment with unicode µ # noqa: E501
RUF100_3.py:25:11: RUF100 [*] Unused `noqa` directive (unused: `E501`) RUF100_3.py:25:11: RUF100 [*] Unused `noqa` directive (unused: `E501`)
| |
@ -369,6 +372,8 @@ RUF100_3.py:25:11: RUF100 [*] Unused `noqa` directive (unused: `E501`)
24 | print(a) # noqa: E501, F821 comment 24 | print(a) # noqa: E501, F821 comment
25 | print(a) # noqa: E501, F821 comment 25 | print(a) # noqa: E501, F821 comment
| ^^^^^^^^^^^^^^^^^^ RUF100 | ^^^^^^^^^^^^^^^^^^ RUF100
26 |
27 | print(a) # comment with unicode µ # noqa: E501
| |
= help: Remove unused `noqa` directive = help: Remove unused `noqa` directive
@ -378,5 +383,50 @@ RUF100_3.py:25:11: RUF100 [*] Unused `noqa` directive (unused: `E501`)
24 24 | print(a) # noqa: E501, F821 comment 24 24 | print(a) # noqa: E501, F821 comment
25 |-print(a) # noqa: E501, F821 comment 25 |-print(a) # noqa: E501, F821 comment
25 |+print(a) # noqa: 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
RUF100_3.py:27:7: F821 Undefined name `a`
|
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
|
RUF100_3.py:27:39: 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
|
= 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
RUF100_3.py:28:39: RUF100 [*] Unused `noqa` directive (unused: `E501`)
|
27 | print(a) # comment with unicode µ # noqa: E501
28 | 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