Avoid allocations for isort module names (#11251)

## Summary

Random refactor I noticed when investigating the F401 changes. We don't
need to allocate in most cases here.
This commit is contained in:
Charlie Marsh 2024-05-02 12:17:56 -07:00 committed by GitHub
parent 3a7c01b365
commit 9a1f6f6762
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 50 additions and 35 deletions

View file

@ -109,7 +109,7 @@ pub(crate) fn definitions(checker: &mut Checker) {
}; };
let definitions = std::mem::take(&mut checker.semantic.definitions); let definitions = std::mem::take(&mut checker.semantic.definitions);
let mut overloaded_name: Option<String> = None; let mut overloaded_name: Option<&str> = None;
for ContextualizedDefinition { for ContextualizedDefinition {
definition, definition,
visibility, visibility,
@ -127,7 +127,7 @@ pub(crate) fn definitions(checker: &mut Checker) {
if !overloaded_name.is_some_and(|overloaded_name| { if !overloaded_name.is_some_and(|overloaded_name| {
flake8_annotations::helpers::is_overload_impl( flake8_annotations::helpers::is_overload_impl(
definition, definition,
&overloaded_name, overloaded_name,
&checker.semantic, &checker.semantic,
) )
}) { }) {

View file

@ -877,7 +877,7 @@ pub(crate) fn statement(stmt: &Stmt, checker: &mut Checker) {
if !matches!(checker.semantic.current_scope().kind, ScopeKind::Module) { if !matches!(checker.semantic.current_scope().kind, ScopeKind::Module) {
checker.diagnostics.push(Diagnostic::new( checker.diagnostics.push(Diagnostic::new(
pyflakes::rules::UndefinedLocalWithNestedImportStarUsage { pyflakes::rules::UndefinedLocalWithNestedImportStarUsage {
name: helpers::format_import_from(level, module), name: helpers::format_import_from(level, module).to_string(),
}, },
stmt.range(), stmt.range(),
)); ));
@ -886,7 +886,7 @@ pub(crate) fn statement(stmt: &Stmt, checker: &mut Checker) {
if checker.enabled(Rule::UndefinedLocalWithImportStar) { if checker.enabled(Rule::UndefinedLocalWithImportStar) {
checker.diagnostics.push(Diagnostic::new( checker.diagnostics.push(Diagnostic::new(
pyflakes::rules::UndefinedLocalWithImportStar { pyflakes::rules::UndefinedLocalWithImportStar {
name: helpers::format_import_from(level, module), name: helpers::format_import_from(level, module).to_string(),
}, },
stmt.range(), stmt.range(),
)); ));

View file

@ -17,10 +17,13 @@ use crate::importer::{ImportRequest, Importer};
use crate::settings::types::PythonVersion; use crate::settings::types::PythonVersion;
/// Return the name of the function, if it's overloaded. /// Return the name of the function, if it's overloaded.
pub(crate) fn overloaded_name(definition: &Definition, semantic: &SemanticModel) -> Option<String> { pub(crate) fn overloaded_name<'a>(
definition: &'a Definition,
semantic: &SemanticModel,
) -> Option<&'a str> {
let function = definition.as_function_def()?; let function = definition.as_function_def()?;
if visibility::is_overload(&function.decorator_list, semantic) { if visibility::is_overload(&function.decorator_list, semantic) {
Some(function.name.to_string()) Some(function.name.as_str())
} else { } else {
None None
} }

View file

@ -29,29 +29,38 @@ pub(crate) struct CommentSet<'a> {
pub(crate) inline: Vec<Cow<'a, str>>, pub(crate) inline: Vec<Cow<'a, str>>,
} }
pub(crate) trait Importable { pub(crate) trait Importable<'a> {
fn module_name(&self) -> String; fn module_name(&self) -> Cow<'a, str>;
fn module_base(&self) -> String;
}
impl Importable for AliasData<'_> { fn module_base(&self) -> Cow<'a, str> {
fn module_name(&self) -> String { match self.module_name() {
self.name.to_string() Cow::Borrowed(module_name) => Cow::Borrowed(
module_name
.split('.')
.next()
.expect("module to include at least one segment"),
),
Cow::Owned(module_name) => Cow::Owned(
module_name
.split('.')
.next()
.expect("module to include at least one segment")
.to_owned(),
),
} }
fn module_base(&self) -> String {
self.module_name().split('.').next().unwrap().to_string()
} }
} }
impl Importable for ImportFromData<'_> { impl<'a> Importable<'a> for AliasData<'a> {
fn module_name(&self) -> String { fn module_name(&self) -> Cow<'a, str> {
Cow::Borrowed(self.name)
}
}
impl<'a> Importable<'a> for ImportFromData<'a> {
fn module_name(&self) -> Cow<'a, str> {
format_import_from(self.level, self.module) format_import_from(self.level, self.module)
} }
fn module_base(&self) -> String {
self.module_name().split('.').next().unwrap().to_string()
}
} }
#[derive(Debug, Default)] #[derive(Debug, Default)]

View file

@ -715,17 +715,21 @@ where
/// assert_eq!(format_import_from(1, None), ".".to_string()); /// assert_eq!(format_import_from(1, None), ".".to_string());
/// assert_eq!(format_import_from(1, Some("foo")), ".foo".to_string()); /// assert_eq!(format_import_from(1, Some("foo")), ".foo".to_string());
/// ``` /// ```
pub fn format_import_from(level: u32, module: Option<&str>) -> String { pub fn format_import_from(level: u32, module: Option<&str>) -> Cow<str> {
let mut module_name = String::with_capacity(16); match (level, module) {
if level > 0 { (0, Some(module)) => Cow::Borrowed(module),
(level, module) => {
let mut module_name =
String::with_capacity((level as usize) + module.map_or(0, str::len));
for _ in 0..level { for _ in 0..level {
module_name.push('.'); module_name.push('.');
} }
}
if let Some(module) = module { if let Some(module) = module {
module_name.push_str(module); module_name.push_str(module);
} }
module_name Cow::Owned(module_name)
}
}
} }
/// Format the member reference name for a relative import. /// Format the member reference name for a relative import.
@ -740,9 +744,8 @@ pub fn format_import_from(level: u32, module: Option<&str>) -> String {
/// assert_eq!(format_import_from_member(1, Some("foo"), "bar"), ".foo.bar".to_string()); /// assert_eq!(format_import_from_member(1, Some("foo"), "bar"), ".foo.bar".to_string());
/// ``` /// ```
pub fn format_import_from_member(level: u32, module: Option<&str>, member: &str) -> String { pub fn format_import_from_member(level: u32, module: Option<&str>, member: &str) -> String {
let mut qualified_name = String::with_capacity( let mut qualified_name =
(level as usize) + module.as_ref().map_or(0, |module| module.len()) + 1 + member.len(), String::with_capacity((level as usize) + module.map_or(0, str::len) + 1 + member.len());
);
if level > 0 { if level > 0 {
for _ in 0..level { for _ in 0..level {
qualified_name.push('.'); qualified_name.push('.');