diff --git a/crates/ruff/resources/test/fixtures/pydocstyle/bom.py b/crates/ruff/resources/test/fixtures/pydocstyle/bom.py new file mode 100644 index 0000000000..c5a58c645f --- /dev/null +++ b/crates/ruff/resources/test/fixtures/pydocstyle/bom.py @@ -0,0 +1 @@ +''' SAM macro definitions ''' diff --git a/crates/ruff/src/rules/pydocstyle/mod.rs b/crates/ruff/src/rules/pydocstyle/mod.rs index c4e4bb5800..7d84a359d8 100644 --- a/crates/ruff/src/rules/pydocstyle/mod.rs +++ b/crates/ruff/src/rules/pydocstyle/mod.rs @@ -59,7 +59,7 @@ mod tests { #[test_case(Rule::PublicMethod, Path::new("setter.py"); "D102_1")] #[test_case(Rule::PublicModule, Path::new("D.py"); "D100")] #[test_case(Rule::PublicNestedClass, Path::new("D.py"); "D106")] - #[test_case(Rule::PublicPackage, Path::new("D.py"); "D104")] + #[test_case(Rule::PublicPackage, Path::new("D.py"); "D104_0")] #[test_case(Rule::PublicPackage, Path::new("D104/__init__.py"); "D104_1")] #[test_case(Rule::SectionNameEndsInColon, Path::new("D.py"); "D416")] #[test_case(Rule::SectionNotOverIndented, Path::new("sections.py"); "D214")] @@ -88,6 +88,16 @@ mod tests { Ok(()) } + #[test] + fn bom() -> Result<()> { + let diagnostics = test_path( + Path::new("pydocstyle/bom.py"), + &settings::Settings::for_rule(Rule::TripleSingleQuotes), + )?; + assert_yaml_snapshot!(diagnostics); + Ok(()) + } + #[test] fn d417_unspecified() -> Result<()> { let diagnostics = test_path( diff --git a/crates/ruff/src/rules/pydocstyle/snapshots/ruff__rules__pydocstyle__tests__bom.snap b/crates/ruff/src/rules/pydocstyle/snapshots/ruff__rules__pydocstyle__tests__bom.snap new file mode 100644 index 0000000000..c2b961b8c2 --- /dev/null +++ b/crates/ruff/src/rules/pydocstyle/snapshots/ruff__rules__pydocstyle__tests__bom.snap @@ -0,0 +1,15 @@ +--- +source: crates/ruff/src/rules/pydocstyle/mod.rs +expression: diagnostics +--- +- kind: + TripleSingleQuotes: ~ + location: + row: 1 + column: 0 + end_location: + row: 1 + column: 29 + fix: ~ + parent: ~ + diff --git a/crates/ruff/src/source_code/locator.rs b/crates/ruff/src/source_code/locator.rs index 70d1d2ddc5..fd4950f561 100644 --- a/crates/ruff/src/source_code/locator.rs +++ b/crates/ruff/src/source_code/locator.rs @@ -35,6 +35,12 @@ fn index_utf8(contents: &str) -> Vec> { let mut current_byte_offset = 0; let mut previous_char = '\0'; for char in contents.chars() { + // Skip BOM. + if previous_char == '\0' && char == '\u{feff}' { + current_byte_offset += char.len_utf8(); + continue; + } + current_row.push(current_byte_offset); if char == '\n' { if previous_char == '\r' {