Compare commits
3 Commits
dcreager/f
...
charlie/bi
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b7517d4511 | ||
|
|
da8481c97d | ||
|
|
cd5c69b61c |
@@ -927,10 +927,9 @@ where
|
|||||||
self.add_binding(
|
self.add_binding(
|
||||||
name,
|
name,
|
||||||
Binding {
|
Binding {
|
||||||
kind: BindingKind::SubmoduleImportation(SubmoduleImportation {
|
kind: BindingKind::SubmoduleImportation(Box::new(
|
||||||
name,
|
SubmoduleImportation { name, full_name },
|
||||||
full_name,
|
)),
|
||||||
}),
|
|
||||||
runtime_usage: None,
|
runtime_usage: None,
|
||||||
synthetic_usage: None,
|
synthetic_usage: None,
|
||||||
typing_usage: None,
|
typing_usage: None,
|
||||||
@@ -954,7 +953,10 @@ where
|
|||||||
self.add_binding(
|
self.add_binding(
|
||||||
name,
|
name,
|
||||||
Binding {
|
Binding {
|
||||||
kind: BindingKind::Importation(Importation { name, full_name }),
|
kind: BindingKind::Importation(Box::new(Importation {
|
||||||
|
name,
|
||||||
|
full_name,
|
||||||
|
})),
|
||||||
runtime_usage: None,
|
runtime_usage: None,
|
||||||
synthetic_usage: if is_explicit_reexport {
|
synthetic_usage: if is_explicit_reexport {
|
||||||
Some((self.ctx.scope_id, alias.range()))
|
Some((self.ctx.scope_id, alias.range()))
|
||||||
@@ -1307,10 +1309,10 @@ where
|
|||||||
self.add_binding(
|
self.add_binding(
|
||||||
name,
|
name,
|
||||||
Binding {
|
Binding {
|
||||||
kind: BindingKind::FromImportation(FromImportation {
|
kind: BindingKind::FromImportation(Box::new(FromImportation {
|
||||||
name,
|
name,
|
||||||
full_name,
|
full_name,
|
||||||
}),
|
})),
|
||||||
runtime_usage: None,
|
runtime_usage: None,
|
||||||
synthetic_usage: if is_explicit_reexport {
|
synthetic_usage: if is_explicit_reexport {
|
||||||
Some((self.ctx.scope_id, alias.range()))
|
Some((self.ctx.scope_id, alias.range()))
|
||||||
@@ -4412,13 +4414,13 @@ impl<'a> Checker<'a> {
|
|||||||
// import pyarrow.csv
|
// import pyarrow.csv
|
||||||
// print(pa.csv.read_csv("test.csv"))
|
// print(pa.csv.read_csv("test.csv"))
|
||||||
match &self.ctx.bindings[*index].kind {
|
match &self.ctx.bindings[*index].kind {
|
||||||
BindingKind::Importation(Importation { name, full_name })
|
BindingKind::Importation(import) => {
|
||||||
| BindingKind::SubmoduleImportation(SubmoduleImportation { name, full_name }) =>
|
let name = import.name;
|
||||||
{
|
let full_name = import.full_name;
|
||||||
let has_alias = full_name
|
let has_alias = full_name
|
||||||
.split('.')
|
.split('.')
|
||||||
.last()
|
.last()
|
||||||
.map(|segment| &segment != name)
|
.map(|segment| segment != name)
|
||||||
.unwrap_or_default();
|
.unwrap_or_default();
|
||||||
if has_alias {
|
if has_alias {
|
||||||
// Mark the sub-importation as used.
|
// Mark the sub-importation as used.
|
||||||
@@ -4431,11 +4433,32 @@ impl<'a> Checker<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
BindingKind::FromImportation(FromImportation { name, full_name }) => {
|
BindingKind::SubmoduleImportation(import) => {
|
||||||
|
let name = import.name;
|
||||||
|
let full_name = import.full_name;
|
||||||
let has_alias = full_name
|
let has_alias = full_name
|
||||||
.split('.')
|
.split('.')
|
||||||
.last()
|
.last()
|
||||||
.map(|segment| &segment != name)
|
.map(|segment| segment != name)
|
||||||
|
.unwrap_or_default();
|
||||||
|
if has_alias {
|
||||||
|
// Mark the sub-importation as used.
|
||||||
|
if let Some(index) = scope.get(full_name) {
|
||||||
|
self.ctx.bindings[*index].mark_used(
|
||||||
|
self.ctx.scope_id,
|
||||||
|
expr.range(),
|
||||||
|
context,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
BindingKind::FromImportation(import) => {
|
||||||
|
let name = import.name;
|
||||||
|
let full_name = &import.full_name;
|
||||||
|
let has_alias = full_name
|
||||||
|
.split('.')
|
||||||
|
.last()
|
||||||
|
.map(|segment| segment != name)
|
||||||
.unwrap_or_default();
|
.unwrap_or_default();
|
||||||
if has_alias {
|
if has_alias {
|
||||||
// Mark the sub-importation as used.
|
// Mark the sub-importation as used.
|
||||||
@@ -4665,10 +4688,8 @@ impl<'a> Checker<'a> {
|
|||||||
// Grab the existing bound __all__ values.
|
// Grab the existing bound __all__ values.
|
||||||
if let StmtKind::AugAssign { .. } = &parent.node {
|
if let StmtKind::AugAssign { .. } = &parent.node {
|
||||||
if let Some(index) = scope.get("__all__") {
|
if let Some(index) = scope.get("__all__") {
|
||||||
if let BindingKind::Export(Export { names: existing }) =
|
if let BindingKind::Export(export) = &self.ctx.bindings[*index].kind {
|
||||||
&self.ctx.bindings[*index].kind
|
names.extend(&export.names);
|
||||||
{
|
|
||||||
names.extend_from_slice(existing);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4693,7 +4714,7 @@ impl<'a> Checker<'a> {
|
|||||||
self.add_binding(
|
self.add_binding(
|
||||||
id,
|
id,
|
||||||
Binding {
|
Binding {
|
||||||
kind: BindingKind::Export(Export { names: all_names }),
|
kind: BindingKind::Export(Box::new(Export { names: all_names })),
|
||||||
runtime_usage: None,
|
runtime_usage: None,
|
||||||
synthetic_usage: None,
|
synthetic_usage: None,
|
||||||
typing_usage: None,
|
typing_usage: None,
|
||||||
@@ -4981,7 +5002,7 @@ impl<'a> Checker<'a> {
|
|||||||
.get("__all__")
|
.get("__all__")
|
||||||
.map(|index| &self.ctx.bindings[*index])
|
.map(|index| &self.ctx.bindings[*index])
|
||||||
.and_then(|binding| match &binding.kind {
|
.and_then(|binding| match &binding.kind {
|
||||||
BindingKind::Export(Export { names }) => Some((names, binding.range)),
|
BindingKind::Export(export) => Some((&export.names, binding.range)),
|
||||||
_ => None,
|
_ => None,
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -5013,7 +5034,7 @@ impl<'a> Checker<'a> {
|
|||||||
.get("__all__")
|
.get("__all__")
|
||||||
.map(|index| &self.ctx.bindings[*index])
|
.map(|index| &self.ctx.bindings[*index])
|
||||||
.and_then(|binding| match &binding.kind {
|
.and_then(|binding| match &binding.kind {
|
||||||
BindingKind::Export(Export { names }) => Some((names.as_slice(), binding.range)),
|
BindingKind::Export(export) => Some((export.names.as_slice(), binding.range)),
|
||||||
_ => None,
|
_ => None,
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -5223,14 +5244,9 @@ impl<'a> Checker<'a> {
|
|||||||
let binding = &self.ctx.bindings[*index];
|
let binding = &self.ctx.bindings[*index];
|
||||||
|
|
||||||
let full_name = match &binding.kind {
|
let full_name = match &binding.kind {
|
||||||
BindingKind::Importation(Importation { full_name, .. }) => full_name,
|
BindingKind::Importation(import) => import.full_name,
|
||||||
BindingKind::FromImportation(FromImportation { full_name, .. }) => {
|
BindingKind::FromImportation(import) => import.full_name.as_str(),
|
||||||
full_name.as_str()
|
BindingKind::SubmoduleImportation(import) => import.full_name,
|
||||||
}
|
|
||||||
BindingKind::SubmoduleImportation(SubmoduleImportation {
|
|
||||||
full_name,
|
|
||||||
..
|
|
||||||
}) => full_name,
|
|
||||||
_ => continue,
|
_ => continue,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
use ruff_diagnostics::{Diagnostic, Violation};
|
use ruff_diagnostics::{Diagnostic, Violation};
|
||||||
use ruff_macros::{derive_message_formats, violation};
|
use ruff_macros::{derive_message_formats, violation};
|
||||||
use ruff_python_semantic::binding::{
|
use ruff_python_semantic::binding::{Binding, BindingKind, ExecutionContext};
|
||||||
Binding, BindingKind, ExecutionContext, FromImportation, Importation, SubmoduleImportation,
|
|
||||||
};
|
|
||||||
|
|
||||||
/// ## What it does
|
/// ## What it does
|
||||||
/// Checks for runtime imports defined in a type-checking block.
|
/// Checks for runtime imports defined in a type-checking block.
|
||||||
@@ -51,9 +49,9 @@ impl Violation for RuntimeImportInTypeCheckingBlock {
|
|||||||
/// TCH004
|
/// TCH004
|
||||||
pub fn runtime_import_in_type_checking_block(binding: &Binding) -> Option<Diagnostic> {
|
pub fn runtime_import_in_type_checking_block(binding: &Binding) -> Option<Diagnostic> {
|
||||||
let full_name = match &binding.kind {
|
let full_name = match &binding.kind {
|
||||||
BindingKind::Importation(Importation { full_name, .. }) => full_name,
|
BindingKind::Importation(import) => import.full_name,
|
||||||
BindingKind::FromImportation(FromImportation { full_name, .. }) => full_name.as_str(),
|
BindingKind::FromImportation(import) => import.full_name.as_str(),
|
||||||
BindingKind::SubmoduleImportation(SubmoduleImportation { full_name, .. }) => full_name,
|
BindingKind::SubmoduleImportation(import) => import.full_name,
|
||||||
_ => return None,
|
_ => return None,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -2,9 +2,7 @@ use std::path::Path;
|
|||||||
|
|
||||||
use ruff_diagnostics::{Diagnostic, Violation};
|
use ruff_diagnostics::{Diagnostic, Violation};
|
||||||
use ruff_macros::{derive_message_formats, violation};
|
use ruff_macros::{derive_message_formats, violation};
|
||||||
use ruff_python_semantic::binding::{
|
use ruff_python_semantic::binding::{Binding, BindingKind, ExecutionContext};
|
||||||
Binding, BindingKind, ExecutionContext, FromImportation, Importation, SubmoduleImportation,
|
|
||||||
};
|
|
||||||
|
|
||||||
use crate::rules::isort::{categorize, ImportSection, ImportType};
|
use crate::rules::isort::{categorize, ImportSection, ImportType};
|
||||||
use crate::settings::Settings;
|
use crate::settings::Settings;
|
||||||
@@ -160,67 +158,68 @@ impl Violation for TypingOnlyStandardLibraryImport {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Return `true` if `this` is implicitly loaded via importing `that`.
|
/// Return `true` if `this` is implicitly loaded via importing `that`.
|
||||||
fn is_implicit_import(this: &Binding, that: &Binding) -> bool {
|
fn is_implicit_import(_this: &Binding, _that: &Binding) -> bool {
|
||||||
match &this.kind {
|
true
|
||||||
BindingKind::Importation(Importation {
|
// match &this.kind {
|
||||||
full_name: this_name,
|
// BindingKind::Importation(Importation {
|
||||||
..
|
// full_name: this_name,
|
||||||
})
|
// ..
|
||||||
| BindingKind::SubmoduleImportation(SubmoduleImportation {
|
// })
|
||||||
name: this_name, ..
|
// | BindingKind::SubmoduleImportation(SubmoduleImportation {
|
||||||
}) => match &that.kind {
|
// name: this_name, ..
|
||||||
BindingKind::FromImportation(FromImportation {
|
// }) => match &that.kind {
|
||||||
full_name: that_name,
|
// BindingKind::FromImportation(FromImportation {
|
||||||
..
|
// full_name: that_name,
|
||||||
}) => {
|
// ..
|
||||||
// Ex) `pkg.A` vs. `pkg`
|
// }) => {
|
||||||
this_name
|
// // Ex) `pkg.A` vs. `pkg`
|
||||||
.rfind('.')
|
// this_name
|
||||||
.map_or(false, |i| this_name[..i] == *that_name)
|
// .rfind('.')
|
||||||
}
|
// .map_or(false, |i| this_name[..i] == *that_name)
|
||||||
BindingKind::Importation(Importation {
|
// }
|
||||||
full_name: that_name,
|
// BindingKind::Importation(Importation {
|
||||||
..
|
// full_name: that_name,
|
||||||
})
|
// ..
|
||||||
| BindingKind::SubmoduleImportation(SubmoduleImportation {
|
// })
|
||||||
name: that_name, ..
|
// | BindingKind::SubmoduleImportation(SubmoduleImportation {
|
||||||
}) => {
|
// name: that_name, ..
|
||||||
// Ex) `pkg.A` vs. `pkg.B`
|
// }) => {
|
||||||
this_name == that_name
|
// // Ex) `pkg.A` vs. `pkg.B`
|
||||||
}
|
// this_name == that_name
|
||||||
_ => false,
|
// }
|
||||||
},
|
// _ => false,
|
||||||
BindingKind::FromImportation(FromImportation {
|
// },
|
||||||
full_name: this_name,
|
// BindingKind::FromImportation(FromImportation {
|
||||||
..
|
// full_name: this_name,
|
||||||
}) => match &that.kind {
|
// ..
|
||||||
BindingKind::Importation(Importation {
|
// }) => match &that.kind {
|
||||||
full_name: that_name,
|
// BindingKind::Importation(Importation {
|
||||||
..
|
// full_name: that_name,
|
||||||
})
|
// ..
|
||||||
| BindingKind::SubmoduleImportation(SubmoduleImportation {
|
// })
|
||||||
name: that_name, ..
|
// | BindingKind::SubmoduleImportation(SubmoduleImportation {
|
||||||
}) => {
|
// name: that_name, ..
|
||||||
// Ex) `pkg.A` vs. `pkg`
|
// }) => {
|
||||||
this_name
|
// // Ex) `pkg.A` vs. `pkg`
|
||||||
.rfind('.')
|
// this_name
|
||||||
.map_or(false, |i| &this_name[..i] == *that_name)
|
// .rfind('.')
|
||||||
}
|
// .map_or(false, |i| &this_name[..i] == *that_name)
|
||||||
BindingKind::FromImportation(FromImportation {
|
// }
|
||||||
full_name: that_name,
|
// BindingKind::FromImportation(FromImportation {
|
||||||
..
|
// full_name: that_name,
|
||||||
}) => {
|
// ..
|
||||||
// Ex) `pkg.A` vs. `pkg.B`
|
// }) => {
|
||||||
this_name.rfind('.').map_or(false, |i| {
|
// // Ex) `pkg.A` vs. `pkg.B`
|
||||||
that_name
|
// this_name.rfind('.').map_or(false, |i| {
|
||||||
.rfind('.')
|
// that_name
|
||||||
.map_or(false, |j| this_name[..i] == that_name[..j])
|
// .rfind('.')
|
||||||
})
|
// .map_or(false, |j| this_name[..i] == that_name[..j])
|
||||||
}
|
// })
|
||||||
_ => false,
|
// }
|
||||||
},
|
// _ => false,
|
||||||
_ => false,
|
// },
|
||||||
}
|
// _ => false,
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return `true` if `name` is exempt from typing-only enforcement.
|
/// Return `true` if `name` is exempt from typing-only enforcement.
|
||||||
@@ -257,9 +256,9 @@ pub fn typing_only_runtime_import(
|
|||||||
}
|
}
|
||||||
|
|
||||||
let full_name = match &binding.kind {
|
let full_name = match &binding.kind {
|
||||||
BindingKind::Importation(Importation { full_name, .. }) => full_name,
|
BindingKind::Importation(import) => import.full_name,
|
||||||
BindingKind::FromImportation(FromImportation { full_name, .. }) => full_name.as_str(),
|
BindingKind::FromImportation(import) => import.full_name.as_str(),
|
||||||
BindingKind::SubmoduleImportation(SubmoduleImportation { full_name, .. }) => full_name,
|
BindingKind::SubmoduleImportation(import) => import.full_name,
|
||||||
_ => return None,
|
_ => return None,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ use rustpython_parser::ast::{Expr, ExprKind};
|
|||||||
use ruff_diagnostics::Violation;
|
use ruff_diagnostics::Violation;
|
||||||
use ruff_diagnostics::{Diagnostic, DiagnosticKind};
|
use ruff_diagnostics::{Diagnostic, DiagnosticKind};
|
||||||
use ruff_macros::{derive_message_formats, violation};
|
use ruff_macros::{derive_message_formats, violation};
|
||||||
use ruff_python_semantic::binding::{BindingKind, Importation};
|
use ruff_python_semantic::binding::BindingKind;
|
||||||
|
|
||||||
use crate::checkers::ast::Checker;
|
use crate::checkers::ast::Checker;
|
||||||
use crate::registry::Rule;
|
use crate::registry::Rule;
|
||||||
@@ -85,11 +85,8 @@ pub fn check_call(checker: &mut Checker, func: &Expr) {
|
|||||||
// irrelevant bindings (like non-Pandas imports).
|
// irrelevant bindings (like non-Pandas imports).
|
||||||
if let ExprKind::Name { id, .. } = &value.node {
|
if let ExprKind::Name { id, .. } = &value.node {
|
||||||
if checker.ctx.find_binding(id).map_or(true, |binding| {
|
if checker.ctx.find_binding(id).map_or(true, |binding| {
|
||||||
if let BindingKind::Importation(Importation {
|
if let BindingKind::Importation(import) = &binding.kind {
|
||||||
full_name: module, ..
|
import.full_name != "pandas"
|
||||||
}) = &binding.kind
|
|
||||||
{
|
|
||||||
module != &"pandas"
|
|
||||||
} else {
|
} else {
|
||||||
matches!(
|
matches!(
|
||||||
binding.kind,
|
binding.kind,
|
||||||
|
|||||||
@@ -59,45 +59,28 @@ impl<'a> Binding<'a> {
|
|||||||
|
|
||||||
pub fn redefines(&self, existing: &'a Binding) -> bool {
|
pub fn redefines(&self, existing: &'a Binding) -> bool {
|
||||||
match &self.kind {
|
match &self.kind {
|
||||||
BindingKind::Importation(Importation { full_name, .. }) => {
|
BindingKind::Importation(import) => {
|
||||||
if let BindingKind::SubmoduleImportation(SubmoduleImportation {
|
if let BindingKind::SubmoduleImportation(existing) = &existing.kind {
|
||||||
full_name: existing,
|
return import.full_name == existing.full_name;
|
||||||
..
|
|
||||||
}) = &existing.kind
|
|
||||||
{
|
|
||||||
return full_name == existing;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
BindingKind::FromImportation(FromImportation { full_name, .. }) => {
|
BindingKind::FromImportation(import) => {
|
||||||
if let BindingKind::SubmoduleImportation(SubmoduleImportation {
|
if let BindingKind::SubmoduleImportation(existing) = &existing.kind {
|
||||||
full_name: existing,
|
return import.full_name == existing.full_name;
|
||||||
..
|
|
||||||
}) = &existing.kind
|
|
||||||
{
|
|
||||||
return full_name == existing;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
BindingKind::SubmoduleImportation(SubmoduleImportation { full_name, .. }) => {
|
BindingKind::SubmoduleImportation(import) => match &existing.kind {
|
||||||
match &existing.kind {
|
BindingKind::Importation(existing) => {
|
||||||
BindingKind::Importation(Importation {
|
return import.full_name == existing.full_name;
|
||||||
full_name: existing,
|
|
||||||
..
|
|
||||||
})
|
|
||||||
| BindingKind::SubmoduleImportation(SubmoduleImportation {
|
|
||||||
full_name: existing,
|
|
||||||
..
|
|
||||||
}) => {
|
|
||||||
return full_name == existing;
|
|
||||||
}
|
}
|
||||||
BindingKind::FromImportation(FromImportation {
|
BindingKind::SubmoduleImportation(existing) => {
|
||||||
full_name: existing,
|
return import.full_name == existing.full_name;
|
||||||
..
|
}
|
||||||
}) => {
|
BindingKind::FromImportation(existing) => {
|
||||||
return full_name == existing;
|
return import.full_name == existing.full_name;
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
},
|
||||||
}
|
|
||||||
BindingKind::Annotation => {
|
BindingKind::Annotation => {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -259,11 +242,11 @@ pub enum BindingKind<'a> {
|
|||||||
Builtin,
|
Builtin,
|
||||||
ClassDefinition,
|
ClassDefinition,
|
||||||
FunctionDefinition,
|
FunctionDefinition,
|
||||||
Export(Export<'a>),
|
Export(Box<Export<'a>>),
|
||||||
FutureImportation,
|
FutureImportation,
|
||||||
Importation(Importation<'a>),
|
Importation(Box<Importation<'a>>),
|
||||||
FromImportation(FromImportation<'a>),
|
FromImportation(Box<FromImportation<'a>>),
|
||||||
SubmoduleImportation(SubmoduleImportation<'a>),
|
SubmoduleImportation(Box<SubmoduleImportation<'a>>),
|
||||||
}
|
}
|
||||||
|
|
||||||
bitflags! {
|
bitflags! {
|
||||||
|
|||||||
@@ -11,10 +11,7 @@ use ruff_python_stdlib::path::is_python_stub_file;
|
|||||||
use ruff_python_stdlib::typing::TYPING_EXTENSIONS;
|
use ruff_python_stdlib::typing::TYPING_EXTENSIONS;
|
||||||
|
|
||||||
use crate::analyze::visibility::{module_visibility, Modifier, VisibleScope};
|
use crate::analyze::visibility::{module_visibility, Modifier, VisibleScope};
|
||||||
use crate::binding::{
|
use crate::binding::{Binding, BindingId, BindingKind, Bindings, Exceptions, ExecutionContext};
|
||||||
Binding, BindingId, BindingKind, Bindings, Exceptions, ExecutionContext, FromImportation,
|
|
||||||
Importation, SubmoduleImportation,
|
|
||||||
};
|
|
||||||
use crate::node::{NodeId, Nodes};
|
use crate::node::{NodeId, Nodes};
|
||||||
use crate::scope::{Scope, ScopeId, ScopeKind, Scopes};
|
use crate::scope::{Scope, ScopeId, ScopeKind, Scopes};
|
||||||
|
|
||||||
@@ -166,10 +163,8 @@ impl<'a> Context<'a> {
|
|||||||
return None;
|
return None;
|
||||||
};
|
};
|
||||||
match &binding.kind {
|
match &binding.kind {
|
||||||
BindingKind::Importation(Importation {
|
BindingKind::Importation(import) => {
|
||||||
full_name: name, ..
|
let name = import.full_name;
|
||||||
})
|
|
||||||
| BindingKind::SubmoduleImportation(SubmoduleImportation { name, .. }) => {
|
|
||||||
if name.starts_with('.') {
|
if name.starts_with('.') {
|
||||||
if let Some(module) = &self.module_path {
|
if let Some(module) = &self.module_path {
|
||||||
let mut source_path = from_relative_import(module, name);
|
let mut source_path = from_relative_import(module, name);
|
||||||
@@ -188,9 +183,28 @@ impl<'a> Context<'a> {
|
|||||||
Some(source_path)
|
Some(source_path)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
BindingKind::FromImportation(FromImportation {
|
BindingKind::SubmoduleImportation(import) => {
|
||||||
full_name: name, ..
|
let name = import.name;
|
||||||
}) => {
|
if name.starts_with('.') {
|
||||||
|
if let Some(module) = &self.module_path {
|
||||||
|
let mut source_path = from_relative_import(module, name);
|
||||||
|
if source_path.is_empty() {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
source_path.extend(call_path.into_iter().skip(1));
|
||||||
|
Some(source_path)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
let mut source_path: CallPath = from_unqualified_name(name);
|
||||||
|
source_path.extend(call_path.into_iter().skip(1));
|
||||||
|
Some(source_path)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
BindingKind::FromImportation(import) => {
|
||||||
|
let name = &import.full_name;
|
||||||
if name.starts_with('.') {
|
if name.starts_with('.') {
|
||||||
if let Some(module) = &self.module_path {
|
if let Some(module) = &self.module_path {
|
||||||
let mut source_path = from_relative_import(module, name);
|
let mut source_path = from_relative_import(module, name);
|
||||||
@@ -243,16 +257,19 @@ impl<'a> Context<'a> {
|
|||||||
// Ex) Given `module="sys"` and `object="exit"`:
|
// Ex) Given `module="sys"` and `object="exit"`:
|
||||||
// `import sys` -> `sys.exit`
|
// `import sys` -> `sys.exit`
|
||||||
// `import sys as sys2` -> `sys2.exit`
|
// `import sys as sys2` -> `sys2.exit`
|
||||||
BindingKind::Importation(Importation { name, full_name }) => {
|
BindingKind::Importation(import) => {
|
||||||
if full_name == &module {
|
if import.full_name == module {
|
||||||
// Verify that `sys` isn't bound in an inner scope.
|
// Verify that `sys` isn't bound in an inner scope.
|
||||||
if self
|
if self
|
||||||
.scopes()
|
.scopes()
|
||||||
.take(scope_index)
|
.take(scope_index)
|
||||||
.all(|scope| scope.get(name).is_none())
|
.all(|scope| scope.get(import.name).is_none())
|
||||||
{
|
{
|
||||||
if let Some(source) = binding.source {
|
if let Some(source) = binding.source {
|
||||||
return Some((self.stmts[source], format!("{name}.{member}")));
|
return Some((
|
||||||
|
self.stmts[source],
|
||||||
|
format!("{}.{member}", import.name),
|
||||||
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -260,17 +277,22 @@ impl<'a> Context<'a> {
|
|||||||
// Ex) Given `module="os.path"` and `object="join"`:
|
// Ex) Given `module="os.path"` and `object="join"`:
|
||||||
// `from os.path import join` -> `join`
|
// `from os.path import join` -> `join`
|
||||||
// `from os.path import join as join2` -> `join2`
|
// `from os.path import join as join2` -> `join2`
|
||||||
BindingKind::FromImportation(FromImportation { name, full_name }) => {
|
BindingKind::FromImportation(import) => {
|
||||||
if let Some((target_module, target_member)) = full_name.split_once('.') {
|
if let Some((target_module, target_member)) =
|
||||||
|
import.full_name.split_once('.')
|
||||||
|
{
|
||||||
if target_module == module && target_member == member {
|
if target_module == module && target_member == member {
|
||||||
// Verify that `join` isn't bound in an inner scope.
|
// Verify that `join` isn't bound in an inner scope.
|
||||||
if self
|
if self
|
||||||
.scopes()
|
.scopes()
|
||||||
.take(scope_index)
|
.take(scope_index)
|
||||||
.all(|scope| scope.get(name).is_none())
|
.all(|scope| scope.get(import.name).is_none())
|
||||||
{
|
{
|
||||||
if let Some(source) = binding.source {
|
if let Some(source) = binding.source {
|
||||||
return Some((self.stmts[source], (*name).to_string()));
|
return Some((
|
||||||
|
self.stmts[source],
|
||||||
|
(*import.name).to_string(),
|
||||||
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -278,16 +300,19 @@ impl<'a> Context<'a> {
|
|||||||
}
|
}
|
||||||
// Ex) Given `module="os"` and `object="name"`:
|
// Ex) Given `module="os"` and `object="name"`:
|
||||||
// `import os.path ` -> `os.name`
|
// `import os.path ` -> `os.name`
|
||||||
BindingKind::SubmoduleImportation(SubmoduleImportation { name, .. }) => {
|
BindingKind::SubmoduleImportation(import) => {
|
||||||
if name == &module {
|
if import.name == module {
|
||||||
// Verify that `os` isn't bound in an inner scope.
|
// Verify that `os` isn't bound in an inner scope.
|
||||||
if self
|
if self
|
||||||
.scopes()
|
.scopes()
|
||||||
.take(scope_index)
|
.take(scope_index)
|
||||||
.all(|scope| scope.get(name).is_none())
|
.all(|scope| scope.get(import.name).is_none())
|
||||||
{
|
{
|
||||||
if let Some(source) = binding.source {
|
if let Some(source) = binding.source {
|
||||||
return Some((self.stmts[source], format!("{name}.{member}")));
|
return Some((
|
||||||
|
self.stmts[source],
|
||||||
|
format!("{}.{member}", import.name),
|
||||||
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user