mirror of https://github.com/astral-sh/ruff
[`flake8_import_conventions`] Avoid false positives for NFKC-normalized `__debug__` import aliases in ICN001 (#19411)
Co-authored-by: Micha Reiser <micha@reiser.io>
This commit is contained in:
parent
18ad2848e3
commit
e917d309f1
|
|
@ -3389,6 +3389,7 @@ dependencies = [
|
||||||
"strum",
|
"strum",
|
||||||
"tempfile",
|
"tempfile",
|
||||||
"toml 0.9.4",
|
"toml 0.9.4",
|
||||||
|
"unicode-normalization",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
|
||||||
|
|
@ -4996,6 +4996,37 @@ fn flake8_import_convention_invalid_aliases_config_module_name() -> Result<()> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn flake8_import_convention_nfkc_normalization() -> Result<()> {
|
||||||
|
let tempdir = TempDir::new()?;
|
||||||
|
let ruff_toml = tempdir.path().join("ruff.toml");
|
||||||
|
fs::write(
|
||||||
|
&ruff_toml,
|
||||||
|
r#"
|
||||||
|
[lint.flake8-import-conventions.aliases]
|
||||||
|
"test.module" = "_﹏𝘥𝘦𝘣𝘶𝘨﹏﹏"
|
||||||
|
"#,
|
||||||
|
)?;
|
||||||
|
|
||||||
|
insta::with_settings!({
|
||||||
|
filters => vec![(tempdir_filter(&tempdir).as_str(), "[TMP]/")]
|
||||||
|
}, {
|
||||||
|
assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME))
|
||||||
|
.args(STDIN_BASE_OPTIONS)
|
||||||
|
.arg("--config")
|
||||||
|
.arg(&ruff_toml)
|
||||||
|
, @r"
|
||||||
|
success: false
|
||||||
|
exit_code: 2
|
||||||
|
----- stdout -----
|
||||||
|
|
||||||
|
----- stderr -----
|
||||||
|
ruff failed
|
||||||
|
Cause: Invalid alias for module 'test.module': alias normalizes to '__debug__', which is not allowed.
|
||||||
|
");});
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn flake8_import_convention_unused_aliased_import() {
|
fn flake8_import_convention_unused_aliased_import() {
|
||||||
assert_cmd_snapshot!(
|
assert_cmd_snapshot!(
|
||||||
|
|
|
||||||
|
|
@ -45,6 +45,7 @@ serde = { workspace = true }
|
||||||
shellexpand = { workspace = true }
|
shellexpand = { workspace = true }
|
||||||
strum = { workspace = true }
|
strum = { workspace = true }
|
||||||
toml = { workspace = true }
|
toml = { workspace = true }
|
||||||
|
unicode-normalization = { workspace = true }
|
||||||
|
|
||||||
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
|
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
|
||||||
etcetera = { workspace = true }
|
etcetera = { workspace = true }
|
||||||
|
|
|
||||||
|
|
@ -250,7 +250,8 @@ impl Configuration {
|
||||||
.unwrap_or_default();
|
.unwrap_or_default();
|
||||||
let flake8_import_conventions = lint
|
let flake8_import_conventions = lint
|
||||||
.flake8_import_conventions
|
.flake8_import_conventions
|
||||||
.map(Flake8ImportConventionsOptions::into_settings)
|
.map(Flake8ImportConventionsOptions::try_into_settings)
|
||||||
|
.transpose()?
|
||||||
.unwrap_or_default();
|
.unwrap_or_default();
|
||||||
|
|
||||||
conflicting_import_settings(&isort, &flake8_import_conventions)?;
|
conflicting_import_settings(&isort, &flake8_import_conventions)?;
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ use serde::{Deserialize, Deserializer, Serialize};
|
||||||
use std::collections::{BTreeMap, BTreeSet};
|
use std::collections::{BTreeMap, BTreeSet};
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use strum::IntoEnumIterator;
|
use strum::IntoEnumIterator;
|
||||||
|
use unicode_normalization::UnicodeNormalization;
|
||||||
|
|
||||||
use crate::settings::LineEnding;
|
use crate::settings::LineEnding;
|
||||||
use ruff_formatter::IndentStyle;
|
use ruff_formatter::IndentStyle;
|
||||||
|
|
@ -1650,7 +1651,9 @@ impl<'de> Deserialize<'de> for Alias {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Flake8ImportConventionsOptions {
|
impl Flake8ImportConventionsOptions {
|
||||||
pub fn into_settings(self) -> flake8_import_conventions::settings::Settings {
|
pub fn try_into_settings(
|
||||||
|
self,
|
||||||
|
) -> anyhow::Result<flake8_import_conventions::settings::Settings> {
|
||||||
let mut aliases: FxHashMap<String, String> = match self.aliases {
|
let mut aliases: FxHashMap<String, String> = match self.aliases {
|
||||||
Some(options_aliases) => options_aliases
|
Some(options_aliases) => options_aliases
|
||||||
.into_iter()
|
.into_iter()
|
||||||
|
|
@ -1666,11 +1669,22 @@ impl Flake8ImportConventionsOptions {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
flake8_import_conventions::settings::Settings {
|
let mut normalized_aliases: FxHashMap<String, String> = FxHashMap::default();
|
||||||
aliases,
|
for (module, alias) in aliases {
|
||||||
|
let normalized_alias = alias.nfkc().collect::<String>();
|
||||||
|
if normalized_alias == "__debug__" {
|
||||||
|
anyhow::bail!(
|
||||||
|
"Invalid alias for module '{module}': alias normalizes to '__debug__', which is not allowed."
|
||||||
|
);
|
||||||
|
}
|
||||||
|
normalized_aliases.insert(module, normalized_alias);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(flake8_import_conventions::settings::Settings {
|
||||||
|
aliases: normalized_aliases,
|
||||||
banned_aliases: self.banned_aliases.unwrap_or_default(),
|
banned_aliases: self.banned_aliases.unwrap_or_default(),
|
||||||
banned_from: self.banned_from.unwrap_or_default(),
|
banned_from: self.banned_from.unwrap_or_default(),
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue