mirror of https://github.com/astral-sh/ruff
Use `qualified_name` terminology in more structs for consistency (#4873)
This commit is contained in:
parent
33434fcb9c
commit
8938b2d555
|
|
@ -57,11 +57,11 @@ pub(crate) fn remove_imports<'a>(
|
|||
// entire statement.
|
||||
let mut found_star = false;
|
||||
for import in imports {
|
||||
let full_name = match import_body.module.as_ref() {
|
||||
let qualified_name = match import_body.module.as_ref() {
|
||||
Some(module_name) => format!("{}.*", compose_module_path(module_name)),
|
||||
None => "*".to_string(),
|
||||
};
|
||||
if import == full_name {
|
||||
if import == qualified_name {
|
||||
found_star = true;
|
||||
} else {
|
||||
bail!("Expected \"*\" for unused import (got: \"{}\")", import);
|
||||
|
|
@ -83,26 +83,26 @@ pub(crate) fn remove_imports<'a>(
|
|||
|
||||
for import in imports {
|
||||
let alias_index = aliases.iter().position(|alias| {
|
||||
let full_name = match import_module {
|
||||
let qualified_name = match import_module {
|
||||
Some((relative, module)) => {
|
||||
let module = module.map(compose_module_path);
|
||||
let member = compose_module_path(&alias.name);
|
||||
let mut full_name = String::with_capacity(
|
||||
let mut qualified_name = String::with_capacity(
|
||||
relative.len() + module.as_ref().map_or(0, String::len) + member.len() + 1,
|
||||
);
|
||||
for _ in 0..relative.len() {
|
||||
full_name.push('.');
|
||||
qualified_name.push('.');
|
||||
}
|
||||
if let Some(module) = module {
|
||||
full_name.push_str(&module);
|
||||
full_name.push('.');
|
||||
qualified_name.push_str(&module);
|
||||
qualified_name.push('.');
|
||||
}
|
||||
full_name.push_str(&member);
|
||||
full_name
|
||||
qualified_name.push_str(&member);
|
||||
qualified_name
|
||||
}
|
||||
None => compose_module_path(&alias.name),
|
||||
};
|
||||
full_name == import
|
||||
qualified_name == import
|
||||
});
|
||||
|
||||
if let Some(index) = alias_index {
|
||||
|
|
@ -170,26 +170,26 @@ pub(crate) fn retain_imports(
|
|||
|
||||
aliases.retain(|alias| {
|
||||
imports.iter().any(|import| {
|
||||
let full_name = match import_module {
|
||||
let qualified_name = match import_module {
|
||||
Some((relative, module)) => {
|
||||
let module = module.map(compose_module_path);
|
||||
let member = compose_module_path(&alias.name);
|
||||
let mut full_name = String::with_capacity(
|
||||
let mut qualified_name = String::with_capacity(
|
||||
relative.len() + module.as_ref().map_or(0, String::len) + member.len() + 1,
|
||||
);
|
||||
for _ in 0..relative.len() {
|
||||
full_name.push('.');
|
||||
qualified_name.push('.');
|
||||
}
|
||||
if let Some(module) = module {
|
||||
full_name.push_str(&module);
|
||||
full_name.push('.');
|
||||
qualified_name.push_str(&module);
|
||||
qualified_name.push('.');
|
||||
}
|
||||
full_name.push_str(&member);
|
||||
full_name
|
||||
qualified_name.push_str(&member);
|
||||
qualified_name
|
||||
}
|
||||
None => compose_module_path(&alias.name),
|
||||
};
|
||||
full_name == *import
|
||||
qualified_name == *import
|
||||
})
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -848,23 +848,25 @@ where
|
|||
}
|
||||
}
|
||||
} else if alias.name.contains('.') && alias.asname.is_none() {
|
||||
// Given `import foo.bar`, `name` would be "foo", and `full_name` would be
|
||||
// Given `import foo.bar`, `name` would be "foo", and `qualified_name` would be
|
||||
// "foo.bar".
|
||||
let name = alias.name.split('.').next().unwrap();
|
||||
let full_name = &alias.name;
|
||||
let qualified_name = &alias.name;
|
||||
self.add_binding(
|
||||
name,
|
||||
alias.range(),
|
||||
BindingKind::SubmoduleImportation(SubmoduleImportation { full_name }),
|
||||
BindingKind::SubmoduleImportation(SubmoduleImportation {
|
||||
qualified_name,
|
||||
}),
|
||||
BindingFlags::empty(),
|
||||
);
|
||||
} else {
|
||||
let name = alias.asname.as_ref().unwrap_or(&alias.name);
|
||||
let full_name = &alias.name;
|
||||
let qualified_name = &alias.name;
|
||||
self.add_binding(
|
||||
name,
|
||||
alias.range(),
|
||||
BindingKind::Importation(Importation { full_name }),
|
||||
BindingKind::Importation(Importation { qualified_name }),
|
||||
if alias
|
||||
.asname
|
||||
.as_ref()
|
||||
|
|
@ -1150,16 +1152,16 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
// Given `from foo import bar`, `name` would be "bar" and `full_name` would
|
||||
// Given `from foo import bar`, `name` would be "bar" and `qualified_name` would
|
||||
// be "foo.bar". Given `from foo import bar as baz`, `name` would be "baz"
|
||||
// and `full_name` would be "foo.bar".
|
||||
// and `qualified_name` would be "foo.bar".
|
||||
let name = alias.asname.as_ref().unwrap_or(&alias.name);
|
||||
let full_name =
|
||||
let qualified_name =
|
||||
helpers::format_import_from_member(level, module, &alias.name);
|
||||
self.add_binding(
|
||||
name,
|
||||
alias.range(),
|
||||
BindingKind::FromImportation(FromImportation { full_name }),
|
||||
BindingKind::FromImportation(FromImportation { qualified_name }),
|
||||
if alias
|
||||
.asname
|
||||
.as_ref()
|
||||
|
|
@ -1195,12 +1197,12 @@ where
|
|||
}
|
||||
|
||||
if self.enabled(Rule::UnconventionalImportAlias) {
|
||||
let full_name =
|
||||
let qualified_name =
|
||||
helpers::format_import_from_member(level, module, &alias.name);
|
||||
if let Some(diagnostic) =
|
||||
flake8_import_conventions::rules::conventional_import_alias(
|
||||
stmt,
|
||||
&full_name,
|
||||
&qualified_name,
|
||||
alias.asname.as_deref(),
|
||||
&self.settings.flake8_import_conventions.aliases,
|
||||
)
|
||||
|
|
@ -1211,12 +1213,12 @@ where
|
|||
|
||||
if self.enabled(Rule::BannedImportAlias) {
|
||||
if let Some(asname) = &alias.asname {
|
||||
let full_name =
|
||||
let qualified_name =
|
||||
helpers::format_import_from_member(level, module, &alias.name);
|
||||
if let Some(diagnostic) =
|
||||
flake8_import_conventions::rules::banned_import_alias(
|
||||
stmt,
|
||||
&full_name,
|
||||
&qualified_name,
|
||||
asname,
|
||||
&self.settings.flake8_import_conventions.banned_aliases,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -88,7 +88,7 @@ impl<'a> Importer<'a> {
|
|||
) -> Result<RuntimeImportEdit> {
|
||||
// Generate the modified import statement.
|
||||
let content = autofix::codemods::retain_imports(
|
||||
&[import.full_name],
|
||||
&[import.qualified_name],
|
||||
import.stmt,
|
||||
self.locator,
|
||||
self.stylist,
|
||||
|
|
@ -120,7 +120,7 @@ impl<'a> Importer<'a> {
|
|||
) -> Result<TypingImportEdit> {
|
||||
// Generate the modified import statement.
|
||||
let content = autofix::codemods::retain_imports(
|
||||
&[import.full_name],
|
||||
&[import.qualified_name],
|
||||
import.stmt,
|
||||
self.locator,
|
||||
self.stylist,
|
||||
|
|
@ -447,7 +447,7 @@ pub(crate) struct StmtImport<'a> {
|
|||
/// The import statement.
|
||||
pub(crate) stmt: &'a Stmt,
|
||||
/// The "full name" of the imported module or member.
|
||||
pub(crate) full_name: &'a str,
|
||||
pub(crate) qualified_name: &'a str,
|
||||
}
|
||||
|
||||
/// The result of an [`Importer::get_or_import_symbol`] call.
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ use crate::registry::AsRule;
|
|||
/// - [PEP 535](https://peps.python.org/pep-0563/#runtime-annotation-resolution-and-type-checking)
|
||||
#[violation]
|
||||
pub struct RuntimeImportInTypeCheckingBlock {
|
||||
full_name: String,
|
||||
qualified_name: String,
|
||||
}
|
||||
|
||||
impl Violation for RuntimeImportInTypeCheckingBlock {
|
||||
|
|
@ -47,9 +47,9 @@ impl Violation for RuntimeImportInTypeCheckingBlock {
|
|||
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
let RuntimeImportInTypeCheckingBlock { full_name } = self;
|
||||
let RuntimeImportInTypeCheckingBlock { qualified_name } = self;
|
||||
format!(
|
||||
"Move import `{full_name}` out of type-checking block. Import is used for more than type hinting."
|
||||
"Move import `{qualified_name}` out of type-checking block. Import is used for more than type hinting."
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -84,7 +84,7 @@ pub(crate) fn runtime_import_in_type_checking_block(
|
|||
{
|
||||
let mut diagnostic = Diagnostic::new(
|
||||
RuntimeImportInTypeCheckingBlock {
|
||||
full_name: qualified_name.to_string(),
|
||||
qualified_name: qualified_name.to_string(),
|
||||
},
|
||||
binding.range,
|
||||
);
|
||||
|
|
@ -110,7 +110,7 @@ pub(crate) fn runtime_import_in_type_checking_block(
|
|||
let add_import_edit = checker.importer.runtime_import_edit(
|
||||
&StmtImport {
|
||||
stmt,
|
||||
full_name: qualified_name,
|
||||
qualified_name,
|
||||
},
|
||||
reference.range().start(),
|
||||
)?;
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ use crate::rules::isort::{categorize, ImportSection, ImportType};
|
|||
/// - [PEP 536](https://peps.python.org/pep-0563/#runtime-annotation-resolution-and-type-checking)
|
||||
#[violation]
|
||||
pub struct TypingOnlyFirstPartyImport {
|
||||
full_name: String,
|
||||
qualified_name: String,
|
||||
}
|
||||
|
||||
impl Violation for TypingOnlyFirstPartyImport {
|
||||
|
|
@ -55,7 +55,7 @@ impl Violation for TypingOnlyFirstPartyImport {
|
|||
fn message(&self) -> String {
|
||||
format!(
|
||||
"Move application import `{}` into a type-checking block",
|
||||
self.full_name
|
||||
self.qualified_name
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -101,7 +101,7 @@ impl Violation for TypingOnlyFirstPartyImport {
|
|||
/// - [PEP 536](https://peps.python.org/pep-0563/#runtime-annotation-resolution-and-type-checking)
|
||||
#[violation]
|
||||
pub struct TypingOnlyThirdPartyImport {
|
||||
full_name: String,
|
||||
qualified_name: String,
|
||||
}
|
||||
|
||||
impl Violation for TypingOnlyThirdPartyImport {
|
||||
|
|
@ -111,7 +111,7 @@ impl Violation for TypingOnlyThirdPartyImport {
|
|||
fn message(&self) -> String {
|
||||
format!(
|
||||
"Move third-party import `{}` into a type-checking block",
|
||||
self.full_name
|
||||
self.qualified_name
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -157,7 +157,7 @@ impl Violation for TypingOnlyThirdPartyImport {
|
|||
/// - [PEP 536](https://peps.python.org/pep-0563/#runtime-annotation-resolution-and-type-checking)
|
||||
#[violation]
|
||||
pub struct TypingOnlyStandardLibraryImport {
|
||||
full_name: String,
|
||||
qualified_name: String,
|
||||
}
|
||||
|
||||
impl Violation for TypingOnlyStandardLibraryImport {
|
||||
|
|
@ -167,7 +167,7 @@ impl Violation for TypingOnlyStandardLibraryImport {
|
|||
fn message(&self) -> String {
|
||||
format!(
|
||||
"Move standard library import `{}` into a type-checking block",
|
||||
self.full_name
|
||||
self.qualified_name
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -274,7 +274,7 @@ pub(crate) fn typing_only_runtime_import(
|
|||
ImportSection::Known(ImportType::LocalFolder | ImportType::FirstParty) => {
|
||||
Diagnostic::new(
|
||||
TypingOnlyFirstPartyImport {
|
||||
full_name: qualified_name.to_string(),
|
||||
qualified_name: qualified_name.to_string(),
|
||||
},
|
||||
binding.range,
|
||||
)
|
||||
|
|
@ -282,14 +282,14 @@ pub(crate) fn typing_only_runtime_import(
|
|||
ImportSection::Known(ImportType::ThirdParty) | ImportSection::UserDefined(_) => {
|
||||
Diagnostic::new(
|
||||
TypingOnlyThirdPartyImport {
|
||||
full_name: qualified_name.to_string(),
|
||||
qualified_name: qualified_name.to_string(),
|
||||
},
|
||||
binding.range,
|
||||
)
|
||||
}
|
||||
ImportSection::Known(ImportType::StandardLibrary) => Diagnostic::new(
|
||||
TypingOnlyStandardLibraryImport {
|
||||
full_name: qualified_name.to_string(),
|
||||
qualified_name: qualified_name.to_string(),
|
||||
},
|
||||
binding.range,
|
||||
),
|
||||
|
|
@ -319,7 +319,7 @@ pub(crate) fn typing_only_runtime_import(
|
|||
let add_import_edit = checker.importer.typing_import_edit(
|
||||
&StmtImport {
|
||||
stmt,
|
||||
full_name: qualified_name,
|
||||
qualified_name,
|
||||
},
|
||||
reference.range().start(),
|
||||
checker.semantic_model(),
|
||||
|
|
|
|||
|
|
@ -40,11 +40,9 @@ pub(crate) fn test_expression(expr: &Expr, model: &SemanticModel) -> Resolution
|
|||
| BindingKind::LoopVar
|
||||
| BindingKind::Global
|
||||
| BindingKind::Nonlocal => Resolution::RelevantLocal,
|
||||
BindingKind::Importation(Importation { full_name: module })
|
||||
if module == "pandas" =>
|
||||
{
|
||||
Resolution::PandasModule
|
||||
}
|
||||
BindingKind::Importation(Importation {
|
||||
qualified_name: module,
|
||||
}) if module == "pandas" => Resolution::PandasModule,
|
||||
_ => Resolution::IrrelevantBinding,
|
||||
}
|
||||
})
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@ pub(crate) fn inplace_argument(
|
|||
matches!(
|
||||
binding.kind,
|
||||
BindingKind::Importation(Importation {
|
||||
full_name: "pandas"
|
||||
qualified_name: "pandas"
|
||||
})
|
||||
)
|
||||
});
|
||||
|
|
|
|||
|
|
@ -165,7 +165,9 @@ pub(crate) fn unused_import(checker: &Checker, scope: &Scope, diagnostics: &mut
|
|||
|
||||
let fix = if !in_init && !in_except_handler && checker.patch(Rule::UnusedImport) {
|
||||
autofix::edits::remove_unused_imports(
|
||||
unused_imports.iter().map(|(full_name, _)| *full_name),
|
||||
unused_imports
|
||||
.iter()
|
||||
.map(|(qualified_name, _)| *qualified_name),
|
||||
stmt,
|
||||
parent,
|
||||
checker.locator,
|
||||
|
|
@ -177,10 +179,10 @@ pub(crate) fn unused_import(checker: &Checker, scope: &Scope, diagnostics: &mut
|
|||
None
|
||||
};
|
||||
|
||||
for (full_name, range) in unused_imports {
|
||||
for (qualified_name, range) in unused_imports {
|
||||
let mut diagnostic = Diagnostic::new(
|
||||
UnusedImport {
|
||||
name: full_name.to_string(),
|
||||
name: qualified_name.to_string(),
|
||||
context: if in_except_handler {
|
||||
Some(UnusedImportContext::ExceptHandler)
|
||||
} else if in_init {
|
||||
|
|
@ -217,10 +219,10 @@ pub(crate) fn unused_import(checker: &Checker, scope: &Scope, diagnostics: &mut
|
|||
let multiple = unused_imports.len() > 1;
|
||||
let in_except_handler =
|
||||
exceptions.intersects(Exceptions::MODULE_NOT_FOUND_ERROR | Exceptions::IMPORT_ERROR);
|
||||
for (full_name, range) in unused_imports {
|
||||
for (qualified_name, range) in unused_imports {
|
||||
let mut diagnostic = Diagnostic::new(
|
||||
UnusedImport {
|
||||
name: full_name.to_string(),
|
||||
name: qualified_name.to_string(),
|
||||
context: if in_except_handler {
|
||||
Some(UnusedImportContext::ExceptHandler)
|
||||
} else if in_init {
|
||||
|
|
|
|||
|
|
@ -493,14 +493,14 @@ impl<'a> ImportReplacer<'a> {
|
|||
fn format_import_from(names: &[&Alias], module: &str) -> String {
|
||||
// Construct the whitespace strings.
|
||||
// Generate the formatted names.
|
||||
let full_names: String = names
|
||||
let qualified_names: String = names
|
||||
.iter()
|
||||
.map(|name| match &name.asname {
|
||||
Some(asname) => format!("{} as {}", name.name, asname),
|
||||
None => format!("{}", name.name),
|
||||
})
|
||||
.join(", ");
|
||||
format!("from {module} import {full_names}")
|
||||
format!("from {module} import {qualified_names}")
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -800,7 +800,7 @@ pub fn format_import_from(level: Option<u32>, module: Option<&str>) -> String {
|
|||
/// assert_eq!(format_import_from_member(Some(1), Some("foo"), "bar"), ".foo.bar".to_string());
|
||||
/// ```
|
||||
pub fn format_import_from_member(level: Option<u32>, module: Option<&str>, member: &str) -> String {
|
||||
let mut full_name = String::with_capacity(
|
||||
let mut qualified_name = String::with_capacity(
|
||||
(level.unwrap_or(0) as usize)
|
||||
+ module.as_ref().map_or(0, |module| module.len())
|
||||
+ 1
|
||||
|
|
@ -808,15 +808,15 @@ pub fn format_import_from_member(level: Option<u32>, module: Option<&str>, membe
|
|||
);
|
||||
if let Some(level) = level {
|
||||
for _ in 0..level {
|
||||
full_name.push('.');
|
||||
qualified_name.push('.');
|
||||
}
|
||||
}
|
||||
if let Some(module) = module {
|
||||
full_name.push_str(module);
|
||||
full_name.push('.');
|
||||
qualified_name.push_str(module);
|
||||
qualified_name.push('.');
|
||||
}
|
||||
full_name.push_str(member);
|
||||
full_name
|
||||
qualified_name.push_str(member);
|
||||
qualified_name
|
||||
}
|
||||
|
||||
/// Create a module path from a (package, path) pair.
|
||||
|
|
|
|||
|
|
@ -48,36 +48,36 @@ impl<'a> Binding<'a> {
|
|||
/// Return `true` if this binding redefines the given binding.
|
||||
pub fn redefines(&self, existing: &'a Binding) -> bool {
|
||||
match &self.kind {
|
||||
BindingKind::Importation(Importation { full_name }) => {
|
||||
BindingKind::Importation(Importation { qualified_name }) => {
|
||||
if let BindingKind::SubmoduleImportation(SubmoduleImportation {
|
||||
full_name: existing,
|
||||
qualified_name: existing,
|
||||
}) = &existing.kind
|
||||
{
|
||||
return full_name == existing;
|
||||
return qualified_name == existing;
|
||||
}
|
||||
}
|
||||
BindingKind::FromImportation(FromImportation { full_name }) => {
|
||||
BindingKind::FromImportation(FromImportation { qualified_name }) => {
|
||||
if let BindingKind::SubmoduleImportation(SubmoduleImportation {
|
||||
full_name: existing,
|
||||
qualified_name: existing,
|
||||
}) = &existing.kind
|
||||
{
|
||||
return full_name == existing;
|
||||
return qualified_name == existing;
|
||||
}
|
||||
}
|
||||
BindingKind::SubmoduleImportation(SubmoduleImportation { full_name }) => {
|
||||
BindingKind::SubmoduleImportation(SubmoduleImportation { qualified_name }) => {
|
||||
match &existing.kind {
|
||||
BindingKind::Importation(Importation {
|
||||
full_name: existing,
|
||||
qualified_name: existing,
|
||||
})
|
||||
| BindingKind::SubmoduleImportation(SubmoduleImportation {
|
||||
full_name: existing,
|
||||
qualified_name: existing,
|
||||
}) => {
|
||||
return full_name == existing;
|
||||
return qualified_name == existing;
|
||||
}
|
||||
BindingKind::FromImportation(FromImportation {
|
||||
full_name: existing,
|
||||
qualified_name: existing,
|
||||
}) => {
|
||||
return full_name == existing;
|
||||
return qualified_name == existing;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
|
@ -104,10 +104,12 @@ impl<'a> Binding<'a> {
|
|||
/// Returns the fully-qualified symbol name, if this symbol was imported from another module.
|
||||
pub fn qualified_name(&self) -> Option<&str> {
|
||||
match &self.kind {
|
||||
BindingKind::Importation(Importation { full_name }) => Some(full_name),
|
||||
BindingKind::FromImportation(FromImportation { full_name }) => Some(full_name),
|
||||
BindingKind::SubmoduleImportation(SubmoduleImportation { full_name }) => {
|
||||
Some(full_name)
|
||||
BindingKind::Importation(Importation { qualified_name }) => Some(qualified_name),
|
||||
BindingKind::FromImportation(FromImportation { qualified_name }) => {
|
||||
Some(qualified_name)
|
||||
}
|
||||
BindingKind::SubmoduleImportation(SubmoduleImportation { qualified_name }) => {
|
||||
Some(qualified_name)
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
|
|
@ -117,14 +119,14 @@ impl<'a> Binding<'a> {
|
|||
/// symbol was imported from another module.
|
||||
pub fn module_name(&self) -> Option<&str> {
|
||||
match &self.kind {
|
||||
BindingKind::Importation(Importation { full_name })
|
||||
| BindingKind::SubmoduleImportation(SubmoduleImportation { full_name }) => {
|
||||
Some(full_name.split('.').next().unwrap_or(full_name))
|
||||
BindingKind::Importation(Importation { qualified_name })
|
||||
| BindingKind::SubmoduleImportation(SubmoduleImportation { qualified_name }) => {
|
||||
Some(qualified_name.split('.').next().unwrap_or(qualified_name))
|
||||
}
|
||||
BindingKind::FromImportation(FromImportation { full_name }) => Some(
|
||||
full_name
|
||||
BindingKind::FromImportation(FromImportation { qualified_name }) => Some(
|
||||
qualified_name
|
||||
.rsplit_once('.')
|
||||
.map_or(full_name, |(module, _)| module),
|
||||
.map_or(qualified_name, |(module, _)| module),
|
||||
),
|
||||
_ => None,
|
||||
}
|
||||
|
|
@ -241,9 +243,9 @@ pub struct Export<'a> {
|
|||
#[derive(Clone, Debug)]
|
||||
pub struct Importation<'a> {
|
||||
/// The full name of the module being imported.
|
||||
/// Ex) Given `import foo`, `full_name` would be "foo".
|
||||
/// Ex) Given `import foo as bar`, `full_name` would be "foo".
|
||||
pub full_name: &'a str,
|
||||
/// Ex) Given `import foo`, `qualified_name` would be "foo".
|
||||
/// Ex) Given `import foo as bar`, `qualified_name` would be "foo".
|
||||
pub qualified_name: &'a str,
|
||||
}
|
||||
|
||||
/// A binding for a member imported from a module, keyed on the name to which the member is bound.
|
||||
|
|
@ -252,9 +254,9 @@ pub struct Importation<'a> {
|
|||
#[derive(Clone, Debug)]
|
||||
pub struct FromImportation {
|
||||
/// The full name of the member being imported.
|
||||
/// Ex) Given `from foo import bar`, `full_name` would be "foo.bar".
|
||||
/// Ex) Given `from foo import bar as baz`, `full_name` would be "foo.bar".
|
||||
pub full_name: String,
|
||||
/// Ex) Given `from foo import bar`, `qualified_name` would be "foo.bar".
|
||||
/// Ex) Given `from foo import bar as baz`, `qualified_name` would be "foo.bar".
|
||||
pub qualified_name: String,
|
||||
}
|
||||
|
||||
/// A binding for a submodule imported from a module, keyed on the name of the parent module.
|
||||
|
|
@ -262,8 +264,8 @@ pub struct FromImportation {
|
|||
#[derive(Clone, Debug)]
|
||||
pub struct SubmoduleImportation<'a> {
|
||||
/// The full name of the submodule being imported.
|
||||
/// Ex) Given `import foo.bar`, `full_name` would be "foo.bar".
|
||||
pub full_name: &'a str,
|
||||
/// Ex) Given `import foo.bar`, `qualified_name` would be "foo.bar".
|
||||
pub qualified_name: &'a str,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, is_macro::Is)]
|
||||
|
|
|
|||
|
|
@ -327,7 +327,9 @@ impl<'a> SemanticModel<'a> {
|
|||
let head = call_path.first()?;
|
||||
let binding = self.find_binding(head)?;
|
||||
match &binding.kind {
|
||||
BindingKind::Importation(Importation { full_name: name }) => {
|
||||
BindingKind::Importation(Importation {
|
||||
qualified_name: name,
|
||||
}) => {
|
||||
if name.starts_with('.') {
|
||||
let mut source_path = from_relative_import(self.module_path?, name);
|
||||
if source_path.is_empty() {
|
||||
|
|
@ -342,13 +344,17 @@ impl<'a> SemanticModel<'a> {
|
|||
Some(source_path)
|
||||
}
|
||||
}
|
||||
BindingKind::SubmoduleImportation(SubmoduleImportation { full_name: name }) => {
|
||||
BindingKind::SubmoduleImportation(SubmoduleImportation {
|
||||
qualified_name: name,
|
||||
}) => {
|
||||
let name = name.split('.').next().unwrap_or(name);
|
||||
let mut source_path: CallPath = from_unqualified_name(name);
|
||||
source_path.extend(call_path.into_iter().skip(1));
|
||||
Some(source_path)
|
||||
}
|
||||
BindingKind::FromImportation(FromImportation { full_name: name }) => {
|
||||
BindingKind::FromImportation(FromImportation {
|
||||
qualified_name: name,
|
||||
}) => {
|
||||
if name.starts_with('.') {
|
||||
let mut source_path = from_relative_import(self.module_path?, name);
|
||||
if source_path.is_empty() {
|
||||
|
|
@ -397,8 +403,8 @@ impl<'a> SemanticModel<'a> {
|
|||
// Ex) Given `module="sys"` and `object="exit"`:
|
||||
// `import sys` -> `sys.exit`
|
||||
// `import sys as sys2` -> `sys2.exit`
|
||||
BindingKind::Importation(Importation { full_name }) => {
|
||||
if full_name == &module {
|
||||
BindingKind::Importation(Importation { qualified_name }) => {
|
||||
if qualified_name == &module {
|
||||
if let Some(source) = binding.source {
|
||||
// Verify that `sys` isn't bound in an inner scope.
|
||||
if self
|
||||
|
|
@ -418,8 +424,9 @@ impl<'a> SemanticModel<'a> {
|
|||
// Ex) Given `module="os.path"` and `object="join"`:
|
||||
// `from os.path import join` -> `join`
|
||||
// `from os.path import join as join2` -> `join2`
|
||||
BindingKind::FromImportation(FromImportation { full_name }) => {
|
||||
if let Some((target_module, target_member)) = full_name.split_once('.') {
|
||||
BindingKind::FromImportation(FromImportation { qualified_name }) => {
|
||||
if let Some((target_module, target_member)) = qualified_name.split_once('.')
|
||||
{
|
||||
if target_module == module && target_member == member {
|
||||
if let Some(source) = binding.source {
|
||||
// Verify that `join` isn't bound in an inner scope.
|
||||
|
|
|
|||
Loading…
Reference in New Issue