Handle relative

This commit is contained in:
Charlie Marsh 2023-07-26 14:17:50 -04:00
parent 68a12f72a4
commit 43eb51b15a
2 changed files with 41 additions and 4 deletions

View File

@ -39,7 +39,9 @@ use ruff_text_size::{TextRange, TextSize};
use ruff_diagnostics::{Diagnostic, IsolationLevel}; use ruff_diagnostics::{Diagnostic, IsolationLevel};
use ruff_python_ast::all::{extract_all_names, DunderAllFlags}; use ruff_python_ast::all::{extract_all_names, DunderAllFlags};
use ruff_python_ast::helpers::{extract_handled_exceptions, to_module_path}; use ruff_python_ast::helpers::{
extract_handled_exceptions, from_relative_import, from_relative_import_parts, to_module_path,
};
use ruff_python_ast::identifier::Identifier; use ruff_python_ast::identifier::Identifier;
use ruff_python_ast::str::trailing_quote; use ruff_python_ast::str::trailing_quote;
use ruff_python_ast::visitor::{walk_except_handler, walk_pattern, Visitor}; use ruff_python_ast::visitor::{walk_except_handler, walk_pattern, Visitor};
@ -397,11 +399,16 @@ where
// be "foo.bar". Given `from foo import bar as baz`, `name` would be "baz" // be "foo.bar". Given `from foo import bar as baz`, `name` would be "baz"
// and `qualified_name` would be "foo.bar". // and `qualified_name` would be "foo.bar".
let name = alias.asname.as_ref().unwrap_or(&alias.name); let name = alias.asname.as_ref().unwrap_or(&alias.name);
let qualified_name = let qualified_name =
helpers::format_import_from_member(level, module, &alias.name); helpers::format_import_from_member(level, module, &alias.name);
let module = module.unwrap(); let call_path = from_relative_import_parts(
let call_path: Box<[&str]> = self.module_path.unwrap_or_default(),
module.split('.').chain(once(alias.name.as_str())).collect(); level,
module,
&alias.name,
);
let call_path: Box<[&str]> = call_path.into_boxed_slice();
self.add_binding( self.add_binding(
name, name,
alias.identifier(), alias.identifier(),

View File

@ -894,6 +894,36 @@ pub fn from_relative_import<'a>(module: &'a [String], name: &'a str) -> CallPath
call_path call_path
} }
pub fn from_relative_import_parts<'a>(
module_path: &'a [String],
level: Option<u32>,
module: Option<&'a str>,
member: &'a str,
) -> CallPath<'a> {
let mut call_path: CallPath = SmallVec::with_capacity(module_path.len() + 1);
// Start with the module path.
call_path.extend(module_path.iter().map(String::as_str));
// Remove segments based on the number of dots.
for _ in 0..level.unwrap_or(0) {
if call_path.is_empty() {
return SmallVec::new();
}
call_path.pop();
}
// Add the remaining segments.
if let Some(module) = module {
call_path.extend(module.split('.'));
}
// Add the member.
call_path.push(member);
call_path
}
/// Given an imported module (based on its relative import level and module name), return the /// Given an imported module (based on its relative import level and module name), return the
/// fully-qualified module path. /// fully-qualified module path.
pub fn resolve_imported_module_path<'a>( pub fn resolve_imported_module_path<'a>(