mirror of
https://github.com/astral-sh/ruff.git
synced 2025-10-07 00:50:37 +00:00
[red-knot] Add initial support for *
imports (#16923)
## Summary This PR adds initial support for `*` imports to red-knot. The approach is to implement a standalone query, called from semantic indexing, that visits the module referenced by the `*` import and collects all global-scope public names that will be imported by the `*` import. The `SemanticIndexBuilder` then adds separate definitions for each of these names, all keyed to the same `ast::Alias` node that represents the `*` import. There are many pieces of `*`-import semantics that are still yet to be done, even with this PR: - This PR does not attempt to implement any of the semantics to do with `__all__`. (If a module defines `__all__`, then only the symbols included in `__all__` are imported, _not_ all public global-scope symbols. - With the logic implemented in this PR as it currently stands, we sometimes incorrectly consider a symbol bound even though it is defined in a branch that is statically known to be dead code, e.g. (assuming the target Python version is set to 3.11): ```py # a.py import sys if sys.version_info < (3, 10): class Foo: ... ``` ```py # b.py from a import * print(Foo) # this is unbound at runtime on 3.11, # but we currently consider it bound with the logic in this PR ``` Implementing these features is important, but is for now deferred to followup PRs. Many thanks to @ntBre, who contributed to this PR in a pairing session on Friday! ## Test Plan Assertions in existing mdtests are adjusted, and several new ones are added.
This commit is contained in:
parent
cba197e3c5
commit
e87fee4b3b
17 changed files with 927 additions and 357 deletions
|
@ -149,7 +149,7 @@ macro_rules! impl_binding_has_ty {
|
|||
#[inline]
|
||||
fn inferred_type<'db>(&self, model: &SemanticModel<'db>) -> Type<'db> {
|
||||
let index = semantic_index(model.db, model.file);
|
||||
let binding = index.definition(self);
|
||||
let binding = index.expect_single_definition(self);
|
||||
binding_type(model.db, binding)
|
||||
}
|
||||
}
|
||||
|
@ -158,10 +158,19 @@ macro_rules! impl_binding_has_ty {
|
|||
|
||||
impl_binding_has_ty!(ast::StmtFunctionDef);
|
||||
impl_binding_has_ty!(ast::StmtClassDef);
|
||||
impl_binding_has_ty!(ast::Alias);
|
||||
impl_binding_has_ty!(ast::Parameter);
|
||||
impl_binding_has_ty!(ast::ParameterWithDefault);
|
||||
|
||||
impl HasType for ast::Alias {
|
||||
fn inferred_type<'db>(&self, model: &SemanticModel<'db>) -> Type<'db> {
|
||||
if &self.name == "*" {
|
||||
return Type::Never;
|
||||
}
|
||||
let index = semantic_index(model.db, model.file);
|
||||
binding_type(model.db, index.expect_single_definition(self))
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use ruff_db::files::system_path_to_file;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue