From 10fef8bd5dfb09637a6408b7a22c485aed016885 Mon Sep 17 00:00:00 2001 From: Dylan <53534755+dylwil3@users.noreply.github.com> Date: Mon, 2 Dec 2024 22:41:47 -0600 Subject: [PATCH] [`flake8-import-conventions`] Improve syntax check for aliases supplied in configuration for `unconventional-import-alias (ICN001)` (#14745) This PR improves on #14477 by: - Ensuring user's do not require the module alias "__debug__", which is unassignable - Validating the linter settings for `lint.flake8-import-conventions.extend-aliases` (whereas previously we only did this for `lint.flake8-import-conventions.aliases`). Closes #14662 --- crates/ruff/tests/lint.rs | 36 ++++++++++++++++++++++++++++ crates/ruff_workspace/src/options.rs | 17 +++++++++++-- ruff.schema.json | 2 +- 3 files changed, 52 insertions(+), 3 deletions(-) diff --git a/crates/ruff/tests/lint.rs b/crates/ruff/tests/lint.rs index 8c7ae672d8002..31153d506dab2 100644 --- a/crates/ruff/tests/lint.rs +++ b/crates/ruff/tests/lint.rs @@ -2003,6 +2003,42 @@ fn flake8_import_convention_invalid_aliases_config_alias_name() -> Result<()> { Ok(()) } +#[test] +fn flake8_import_convention_invalid_aliases_config_extend_alias_name() -> Result<()> { + let tempdir = TempDir::new()?; + let ruff_toml = tempdir.path().join("ruff.toml"); + fs::write( + &ruff_toml, + r#" +[lint.flake8-import-conventions.extend-aliases] +"module.name" = "__debug__" +"#, + )?; + + 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: Failed to parse [TMP]/ruff.toml + Cause: TOML parse error at line 2, column 2 + | + 2 | [lint.flake8-import-conventions.extend-aliases] + | ^^^^ + invalid value: string "__debug__", expected an assignable Python identifier + "###);}); + Ok(()) +} + #[test] fn flake8_import_convention_invalid_aliases_config_module_name() -> Result<()> { let tempdir = TempDir::new()?; diff --git a/crates/ruff_workspace/src/options.rs b/crates/ruff_workspace/src/options.rs index 7da7f9dd5e19a..0d9fc739c557c 100644 --- a/crates/ruff_workspace/src/options.rs +++ b/crates/ruff_workspace/src/options.rs @@ -1342,7 +1342,7 @@ pub struct Flake8ImportConventionsOptions { "dask.dataframe" = "dd" "# )] - pub extend_aliases: Option>, + pub extend_aliases: Option>, /// A mapping from module to its banned import aliases. #[option( @@ -1415,6 +1415,15 @@ impl<'de> Deserialize<'de> for Alias { D: Deserializer<'de>, { let name = String::deserialize(deserializer)?; + // Assigning to "__debug__" is a SyntaxError + // see the note here: + // https://docs.python.org/3/library/constants.html#debug__ + if &*name == "__debug__" { + return Err(de::Error::invalid_value( + de::Unexpected::Str(&name), + &"an assignable Python identifier", + )); + } if is_identifier(&name) { Ok(Self(name)) } else { @@ -1436,7 +1445,11 @@ impl Flake8ImportConventionsOptions { None => flake8_import_conventions::settings::default_aliases(), }; if let Some(extend_aliases) = self.extend_aliases { - aliases.extend(extend_aliases); + aliases.extend( + extend_aliases + .into_iter() + .map(|(module, alias)| (module.into_string(), alias.into_string())), + ); } flake8_import_conventions::settings::Settings { diff --git a/ruff.schema.json b/ruff.schema.json index 025f8e3011999..29c1a05ecfaa1 100644 --- a/ruff.schema.json +++ b/ruff.schema.json @@ -1168,7 +1168,7 @@ "null" ], "additionalProperties": { - "type": "string" + "$ref": "#/definitions/Alias" } } },