|
1 | 1 | //! Interface for editing code snippets. These functions take statements or expressions as input,
|
2 | 2 | //! and return the modified code snippet as output.
|
| 3 | +use std::borrow::Cow; |
| 4 | + |
3 | 5 | use anyhow::{bail, Result};
|
4 | 6 | use libcst_native::{
|
5 | 7 | Codegen, CodegenState, Expression, ImportNames, NameOrAttribute, ParenthesizableWhitespace,
|
6 | 8 | SmallStatement, Statement,
|
7 | 9 | };
|
8 |
| -use ruff_python_ast::name::UnqualifiedName; |
9 | 10 | use smallvec::{smallvec, SmallVec};
|
| 11 | +use unicode_normalization::UnicodeNormalization; |
10 | 12 |
|
| 13 | +use ruff_python_ast::name::UnqualifiedName; |
11 | 14 | use ruff_python_ast::Stmt;
|
12 | 15 | use ruff_python_codegen::Stylist;
|
13 | 16 | use ruff_source_file::Locator;
|
@@ -194,12 +197,16 @@ fn unqualified_name_from_expression<'a>(expr: &'a Expression<'a>) -> Option<Unqu
|
194 | 197 | }
|
195 | 198 |
|
196 | 199 | 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), |
199 | 202 | NameOrAttribute::A(attr) => {
|
200 | 203 | let name = attr.attr.value;
|
201 | 204 | 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 | + ) |
203 | 209 | }
|
204 |
| - } |
| 210 | + }; |
| 211 | + unnormalized.nfkc().collect() |
205 | 212 | }
|
0 commit comments