Config error only when flake8-import-conventions alias conflicts with isort.required-imports bound name (#15918)
Some checks are pending
CI / Determine changes (push) Waiting to run
CI / cargo fmt (push) Waiting to run
CI / cargo clippy (push) Blocked by required conditions
CI / cargo test (linux) (push) Blocked by required conditions
CI / cargo test (linux, release) (push) Blocked by required conditions
CI / cargo test (windows) (push) Blocked by required conditions
CI / cargo test (wasm) (push) Blocked by required conditions
CI / cargo build (release) (push) Waiting to run
CI / cargo build (msrv) (push) Blocked by required conditions
CI / cargo fuzz build (push) Blocked by required conditions
CI / fuzz parser (push) Blocked by required conditions
CI / test scripts (push) Blocked by required conditions
CI / ecosystem (push) Blocked by required conditions
CI / cargo shear (push) Blocked by required conditions
CI / python package (push) Waiting to run
CI / pre-commit (push) Waiting to run
CI / mkdocs (push) Waiting to run
CI / formatter instabilities and black similarity (push) Blocked by required conditions
CI / test ruff-lsp (push) Blocked by required conditions
CI / benchmarks (push) Blocked by required conditions

Previously an error was emitted any time the configuration required both
an import of a module and an alias for that module. However, required
imports could themselves contain an alias, which may or may not agree
with the required alias.

To wit: requiring `import pandas as pd` does not conflict with the
`flake8-import-conventions.alias` config `{"pandas":"pd"}`.

This PR refines the check before throwing an error.

Closes #15911
This commit is contained in:
Dylan 2025-02-04 17:05:35 -06:00 committed by GitHub
parent 4c15d7a559
commit 700e969c56
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 56 additions and 4 deletions

View file

@ -2175,6 +2175,20 @@ fn flake8_import_convention_unused_aliased_import() {
.pass_stdin("1"));
}
#[test]
fn flake8_import_convention_unused_aliased_import_no_conflict() {
assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME))
.args(STDIN_BASE_OPTIONS)
.arg("--config")
.arg(r#"lint.isort.required-imports = ["import pandas as pd"]"#)
.args(["--select", "I002,ICN001,F401"])
.args(["--stdin-filename", "test.py"])
.arg("--unsafe-fixes")
.arg("--fix")
.arg("-")
.pass_stdin("1"));
}
/// Test that private, old-style `TypeVar` generics
/// 1. Get replaced with PEP 695 type parameters (UP046, UP047)
/// 2. Get renamed to remove leading underscores (UP049)

View file

@ -0,0 +1,27 @@
---
source: crates/ruff/tests/lint.rs
info:
program: ruff
args:
- check
- "--no-cache"
- "--output-format"
- concise
- "--config"
- "lint.isort.required-imports = [\"import pandas as pd\"]"
- "--select"
- "I002,ICN001,F401"
- "--stdin-filename"
- test.py
- "--unsafe-fixes"
- "--fix"
- "-"
stdin: "1"
---
success: true
exit_code: 0
----- stdout -----
import pandas as pd
1
----- stderr -----
Found 1 error (1 fixed, 0 remaining).

View file

@ -43,7 +43,7 @@ impl NameImports {
impl NameImport {
/// Returns the name under which the member is bound (e.g., given `from foo import bar as baz`, returns `baz`).
fn bound_name(&self) -> &str {
pub fn bound_name(&self) -> &str {
match self {
NameImport::Import(import) => {
import.name.as_name.as_deref().unwrap_or(&import.name.name)

View file

@ -1576,9 +1576,20 @@ fn conflicting_import_settings(
use std::fmt::Write;
let mut err_body = String::new();
for required_import in &isort.required_imports {
let name = required_import.qualified_name().to_string();
if let Some(alias) = flake8_import_conventions.aliases.get(&name) {
writeln!(err_body, " - `{name}` -> `{alias}`").unwrap();
// Ex: `from foo import bar as baz` OR `import foo.bar as baz`
// - qualified name: `foo.bar`
// - bound name: `baz`
// - conflicts with: `{"foo.bar":"buzz"}`
// - does not conflict with either of
// - `{"bar":"buzz"}`
// - `{"foo.bar":"baz"}`
let qualified_name = required_import.qualified_name().to_string();
let bound_name = required_import.bound_name();
let Some(alias) = flake8_import_conventions.aliases.get(&qualified_name) else {
continue;
};
if alias != bound_name {
writeln!(err_body, " - `{qualified_name}` -> `{alias}`").unwrap();
}
}