diff --git a/Cargo.lock b/Cargo.lock index af6cb8c8da3125..e6d8308ed7fd10 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2319,6 +2319,7 @@ dependencies = [ "thiserror", "toml", "typed-arena", + "unicode-normalization", "unicode-width", "unicode_names2", "url", diff --git a/crates/ruff_linter/Cargo.toml b/crates/ruff_linter/Cargo.toml index c11ba0b9eee79e..b98ee74d72f575 100644 --- a/crates/ruff_linter/Cargo.toml +++ b/crates/ruff_linter/Cargo.toml @@ -69,6 +69,7 @@ toml = { workspace = true } typed-arena = { workspace = true } unicode-width = { workspace = true } unicode_names2 = { workspace = true } +unicode-normalization = { workspace = true } url = { workspace = true } [dev-dependencies] diff --git a/crates/ruff_linter/src/fix/codemods.rs b/crates/ruff_linter/src/fix/codemods.rs index c3c7691726967d..db03b4a8894cc4 100644 --- a/crates/ruff_linter/src/fix/codemods.rs +++ b/crates/ruff_linter/src/fix/codemods.rs @@ -5,6 +5,7 @@ use libcst_native::{ Codegen, CodegenState, Expression, ImportNames, NameOrAttribute, ParenthesizableWhitespace, SmallStatement, Statement, }; +use unicode_normalization::UnicodeNormalization; use ruff_python_ast::name::UnqualifiedName; use smallvec::{smallvec, SmallVec}; @@ -194,12 +195,13 @@ fn unqualified_name_from_expression<'a>(expr: &'a Expression<'a>) -> Option String { - match module { + let unnormalized = match module { NameOrAttribute::N(name) => name.value.to_string(), NameOrAttribute::A(attr) => { let name = attr.attr.value; let prefix = unqualified_name_from_expression(&attr.value); prefix.map_or_else(|| name.to_string(), |prefix| format!("{prefix}.{name}")) } - } + }; + unnormalized.nfkc().collect() }