Use `qualified_name` terminology in more structs for consistency (#4873)

This commit is contained in:
Charlie Marsh 2023-06-05 15:06:48 -04:00 committed by GitHub
parent 33434fcb9c
commit 8938b2d555
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 116 additions and 105 deletions

View File

@ -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
})
});

View File

@ -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,
)

View File

@ -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.

View File

@ -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(),
)?;

View File

@ -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(),

View File

@ -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,
}
})

View File

@ -71,7 +71,7 @@ pub(crate) fn inplace_argument(
matches!(
binding.kind,
BindingKind::Importation(Importation {
full_name: "pandas"
qualified_name: "pandas"
})
)
});

View File

@ -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 {

View File

@ -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}")
}
}

View File

@ -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.

View File

@ -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)]

View File

@ -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.