Skip to content

Commit

Permalink
use never and unbound
Browse files Browse the repository at this point in the history
  • Loading branch information
pilleye committed Oct 15, 2024
1 parent b6faea5 commit 7932d6c
Showing 1 changed file with 10 additions and 8 deletions.
18 changes: 10 additions & 8 deletions crates/red_knot_python_semantic/src/types/infer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1577,7 +1577,7 @@ impl<'db> TypeInferenceBuilder<'db> {
let member_ty = module_ty.member(self.db, &ast::name::Name::new(&name.id));

// TODO: What if it's a union where one of the elements is `Unbound`?
if member_ty.is_unbound() {
if member_ty.is_unbound() || member_ty.is_never() {
self.add_diagnostic(
AnyNodeRef::Alias(alias),
"unresolved-import",
Expand All @@ -1594,7 +1594,9 @@ impl<'db> TypeInferenceBuilder<'db> {
// the runtime error will occur immediately (rather than when the symbol is *used*,
// as would be the case for a symbol with type `Unbound`), so it's appropriate to
// think of the type of the imported symbol as `Unknown` rather than `Unbound`
let ty = member_ty.replace_unbound_with(self.db, Type::Unknown);
let ty = member_ty
.replace_never_with(self.db, Type::Unknown)
.replace_unbound_with(self.db, Type::Unknown);

self.add_declaration_with_binding(alias.into(), definition, ty, ty);
}
Expand Down Expand Up @@ -2207,6 +2209,7 @@ impl<'db> TypeInferenceBuilder<'db> {
return symbol_ty(self.db, enclosing_scope_id, name);
}
}

// No nonlocal binding, check module globals. Avoid infinite recursion if `self.scope`
// already is module globals.
let ty = if file_scope_id.is_global() {
Expand Down Expand Up @@ -3356,20 +3359,19 @@ mod tests {
Ok(())
}

#[test_case(""; "unannotated")]
#[test_case(": int"; "annotated")]
fn imported_unbound_symbol_is_unknown(annotation: &'static str) -> anyhow::Result<()> {
#[test]
fn imported_unbound_symbol_is_unknown() -> anyhow::Result<()> {
let mut db = setup_db();

db.write_files([
("src/package/__init__.py", ""),
("src/package/foo.py", &format!("x{annotation}")),
("src/package/foo.py", "x"),
("src/package/bar.py", "from package.foo import x"),
])?;

// the type as seen from external modules (`Unknown`)
// is different from the type inside the module itself (`Unbound`):
assert_public_ty(&db, "src/package/foo.py", "x", "Unknown");
// is different from the type inside the module itself (`Never`):
assert_public_ty(&db, "src/package/foo.py", "x", "Never");
assert_public_ty(&db, "src/package/bar.py", "x", "Unknown");

Ok(())
Expand Down

0 comments on commit 7932d6c

Please sign in to comment.