mirror of
https://github.com/astral-sh/ruff.git
synced 2025-09-30 13:51:16 +00:00
Skip BOM when inserting start-of-file imports (#7622)
See: https://github.com/astral-sh/ruff/issues/7455#issuecomment-1732387485.
This commit is contained in:
parent
b194f59aab
commit
8ba8896a7f
5 changed files with 39 additions and 4 deletions
4
crates/ruff_linter/resources/test/fixtures/flake8_simplify/SIM105_4.py
vendored
Executable file
4
crates/ruff_linter/resources/test/fixtures/flake8_simplify/SIM105_4.py
vendored
Executable file
|
@ -0,0 +1,4 @@
|
|||
#!/usr/bin/env python
|
||||
try:
|
||||
from __builtin__ import bytes, str, open, super, range, zip, round, int, pow, object, input
|
||||
except ImportError: pass
|
|
@ -64,7 +64,7 @@ impl<'a> Insertion<'a> {
|
|||
// Otherwise, advance to the next row.
|
||||
locator.full_line_end(location)
|
||||
} else {
|
||||
TextSize::default()
|
||||
locator.contents_start()
|
||||
};
|
||||
|
||||
// Skip over commented lines, with whitespace separation.
|
||||
|
|
|
@ -19,6 +19,7 @@ mod tests {
|
|||
#[test_case(Rule::SuppressibleException, Path::new("SIM105_1.py"))]
|
||||
#[test_case(Rule::SuppressibleException, Path::new("SIM105_2.py"))]
|
||||
#[test_case(Rule::SuppressibleException, Path::new("SIM105_3.py"))]
|
||||
#[test_case(Rule::SuppressibleException, Path::new("SIM105_4.py"))]
|
||||
#[test_case(Rule::ReturnInTryExceptFinally, Path::new("SIM107.py"))]
|
||||
#[test_case(Rule::IfElseBlockInsteadOfIfExp, Path::new("SIM108.py"))]
|
||||
#[test_case(Rule::CompareWithTuple, Path::new("SIM109.py"))]
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
---
|
||||
source: crates/ruff_linter/src/rules/flake8_simplify/mod.rs
|
||||
---
|
||||
SIM105_4.py:2:1: SIM105 [*] Use `contextlib.suppress(ImportError)` instead of `try`-`except`-`pass`
|
||||
|
|
||||
1 | #!/usr/bin/env python
|
||||
2 | / try:
|
||||
3 | | from __builtin__ import bytes, str, open, super, range, zip, round, int, pow, object, input
|
||||
4 | | except ImportError: pass
|
||||
| |___________________________^ SIM105
|
||||
|
|
||||
= help: Replace with `contextlib.suppress(ImportError)`
|
||||
|
||||
ℹ Suggested fix
|
||||
1 1 | #!/usr/bin/env python
|
||||
2 |-try:
|
||||
2 |+import contextlib
|
||||
3 |+with contextlib.suppress(ImportError):
|
||||
3 4 | from __builtin__ import bytes, str, open, super, range, zip, round, int, pow, object, input
|
||||
4 |-except ImportError: pass
|
||||
|
||||
|
|
@ -76,7 +76,15 @@ impl<'a> Locator<'a> {
|
|||
if let Some(index) = memrchr2(b'\n', b'\r', bytes) {
|
||||
// SAFETY: Safe because `index < offset`
|
||||
TextSize::try_from(index).unwrap().add(TextSize::from(1))
|
||||
} else if self.contents.starts_with('\u{feff}') {
|
||||
} else {
|
||||
self.contents_start()
|
||||
}
|
||||
}
|
||||
|
||||
/// Computes the start position of the file contents: either the first byte, or the byte after
|
||||
/// the BOM.
|
||||
pub fn contents_start(&self) -> TextSize {
|
||||
if self.contents.starts_with('\u{feff}') {
|
||||
// Skip the BOM.
|
||||
'\u{feff}'.text_len()
|
||||
} else {
|
||||
|
@ -85,9 +93,9 @@ impl<'a> Locator<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Returns `true` if `offset` is at the start of a line.
|
||||
pub fn is_at_start_of_line(&self, offset: TextSize) -> bool {
|
||||
offset == TextSize::from(0)
|
||||
|| self.contents[TextRange::up_to(offset)].ends_with(['\n', '\r'])
|
||||
self.line_start(offset) == offset
|
||||
}
|
||||
|
||||
/// Computes the offset that is right after the newline character that ends `offset`'s line.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue