Skip to content

Commit 41192cb

Browse files
committed
Fix NFKC normalization bug when removing unused imports
1 parent 381bd1f commit 41192cb

File tree

3 files changed

+14
-5
lines changed

3 files changed

+14
-5
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/ruff_linter/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ toml = { workspace = true }
6969
typed-arena = { workspace = true }
7070
unicode-width = { workspace = true }
7171
unicode_names2 = { workspace = true }
72+
unicode-normalization = { workspace = true }
7273
url = { workspace = true }
7374

7475
[dev-dependencies]

crates/ruff_linter/src/fix/codemods.rs

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,16 @@
11
//! Interface for editing code snippets. These functions take statements or expressions as input,
22
//! and return the modified code snippet as output.
3+
use std::borrow::Cow;
4+
35
use anyhow::{bail, Result};
46
use libcst_native::{
57
Codegen, CodegenState, Expression, ImportNames, NameOrAttribute, ParenthesizableWhitespace,
68
SmallStatement, Statement,
79
};
8-
use ruff_python_ast::name::UnqualifiedName;
910
use smallvec::{smallvec, SmallVec};
11+
use unicode_normalization::UnicodeNormalization;
1012

13+
use ruff_python_ast::name::UnqualifiedName;
1114
use ruff_python_ast::Stmt;
1215
use ruff_python_codegen::Stylist;
1316
use ruff_source_file::Locator;
@@ -194,12 +197,16 @@ fn unqualified_name_from_expression<'a>(expr: &'a Expression<'a>) -> Option<Unqu
194197
}
195198

196199
fn qualified_name_from_name_or_attribute(module: &NameOrAttribute) -> String {
197-
match module {
198-
NameOrAttribute::N(name) => name.value.to_string(),
200+
let unnormalized = match module {
201+
NameOrAttribute::N(name) => Cow::Borrowed(name.value),
199202
NameOrAttribute::A(attr) => {
200203
let name = attr.attr.value;
201204
let prefix = unqualified_name_from_expression(&attr.value);
202-
prefix.map_or_else(|| name.to_string(), |prefix| format!("{prefix}.{name}"))
205+
prefix.map_or_else(
206+
|| Cow::Borrowed(name),
207+
|prefix| Cow::Owned(format!("{prefix}.{name}")),
208+
)
203209
}
204-
}
210+
};
211+
unnormalized.nfkc().collect()
205212
}

0 commit comments

Comments
 (0)