mirror of
https://github.com/astral-sh/ruff.git
synced 2025-07-07 21:25:08 +00:00
[isort
] Check full module path against project root(s) when categorizing first-party (#16565)
When attempting to determine whether `import foo.bar.baz` is a known first-party import relative to [user-provided source paths](https://docs.astral.sh/ruff/settings/#src), when `preview` is enabled we now check that `SRC/foo/bar/baz` is a directory or `SRC/foo/bar/baz.py` or `SRC/foo/bar/baz.pyi` exist. Previously, we just checked the analogous thing for `SRC/foo`, but this can be misleading in situations with disjoint namespace packages that share a common base name (e.g. we may be working inside the namespace package `foo.buzz` and importing `foo.bar` from elsewhere). Supersedes #12987 Closes #12984
This commit is contained in:
parent
5e2c818417
commit
965a4dd731
12 changed files with 652 additions and 21 deletions
|
@ -714,6 +714,15 @@ pub trait Imported<'a> {
|
|||
/// Returns the member name of the imported symbol. For a straight import, this is equivalent
|
||||
/// to the qualified name; for a `from` import, this is the name of the imported symbol.
|
||||
fn member_name(&self) -> Cow<'a, str>;
|
||||
|
||||
/// Returns the source module of the imported symbol.
|
||||
///
|
||||
/// For example:
|
||||
///
|
||||
/// - `import foo` returns `["foo"]`
|
||||
/// - `import foo.bar` returns `["foo","bar"]`
|
||||
/// - `from foo import bar` returns `["foo"]`
|
||||
fn source_name(&self) -> &[&'a str];
|
||||
}
|
||||
|
||||
impl<'a> Imported<'a> for Import<'a> {
|
||||
|
@ -731,6 +740,10 @@ impl<'a> Imported<'a> for Import<'a> {
|
|||
fn member_name(&self) -> Cow<'a, str> {
|
||||
Cow::Owned(self.qualified_name().to_string())
|
||||
}
|
||||
|
||||
fn source_name(&self) -> &[&'a str] {
|
||||
self.qualified_name.segments()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Imported<'a> for SubmoduleImport<'a> {
|
||||
|
@ -748,6 +761,10 @@ impl<'a> Imported<'a> for SubmoduleImport<'a> {
|
|||
fn member_name(&self) -> Cow<'a, str> {
|
||||
Cow::Owned(self.qualified_name().to_string())
|
||||
}
|
||||
|
||||
fn source_name(&self) -> &[&'a str] {
|
||||
self.qualified_name.segments()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Imported<'a> for FromImport<'a> {
|
||||
|
@ -765,6 +782,10 @@ impl<'a> Imported<'a> for FromImport<'a> {
|
|||
fn member_name(&self) -> Cow<'a, str> {
|
||||
Cow::Borrowed(self.qualified_name.segments()[self.qualified_name.segments().len() - 1])
|
||||
}
|
||||
|
||||
fn source_name(&self) -> &[&'a str] {
|
||||
self.module_name()
|
||||
}
|
||||
}
|
||||
|
||||
/// A wrapper around an import [`BindingKind`] that can be any of the three types of imports.
|
||||
|
@ -799,6 +820,14 @@ impl<'ast> Imported<'ast> for AnyImport<'_, 'ast> {
|
|||
Self::FromImport(import) => import.member_name(),
|
||||
}
|
||||
}
|
||||
|
||||
fn source_name(&self) -> &[&'ast str] {
|
||||
match self {
|
||||
Self::Import(import) => import.source_name(),
|
||||
Self::SubmoduleImport(import) => import.source_name(),
|
||||
Self::FromImport(import) => import.source_name(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue