Skip to content

Commit

Permalink
use Never type instead of Unknown for unbound public types
Browse files Browse the repository at this point in the history
Uses `Type::Never` instead of `Type::Unknown` for the case where
a publicly available variable is unbound. In the case where it is
unbound, we want a union of its actual type with `Never` instead of
`Unbound`, because the `Unbound` case will cause runtime error.
  • Loading branch information
pilleye committed Sep 30, 2024
1 parent 5118166 commit b67b0b3
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 10 deletions.
8 changes: 2 additions & 6 deletions crates/red_knot_python_semantic/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,7 @@ fn symbol_ty_by_id<'db>(db: &'db dyn Db, scope: ScopeId<'db>, symbol: ScopedSymb
Some(bindings_ty(
db,
use_def.public_bindings(symbol),
use_def
.public_may_be_unbound(symbol)
.then_some(Type::Unknown),
use_def.public_may_be_unbound(symbol).then_some(Type::Never),
))
} else {
None
Expand All @@ -72,9 +70,7 @@ fn symbol_ty_by_id<'db>(db: &'db dyn Db, scope: ScopeId<'db>, symbol: ScopedSymb
bindings_ty(
db,
use_def.public_bindings(symbol),
use_def
.public_may_be_unbound(symbol)
.then_some(Type::Unbound),
use_def.public_may_be_unbound(symbol).then_some(Type::Never),
)
}
}
Expand Down
42 changes: 38 additions & 4 deletions crates/red_knot_python_semantic/src/types/infer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3620,7 +3620,7 @@ mod tests {
)?;

// TODO: sys.version_info, and need to understand @final and @type_check_only
assert_public_ty(&db, "src/a.py", "x", "Unknown | EllipsisType");
assert_public_ty(&db, "src/a.py", "x", "EllipsisType | Unknown");

Ok(())
}
Expand Down Expand Up @@ -3952,6 +3952,40 @@ mod tests {
Ok(())
}

#[test]
fn resolve_unbound_public() -> anyhow::Result<()> {
let mut db = setup_db();

db.write_dedented(
"src/a.py",
"
if flag:
x: int = 1
",
)?;

assert_public_ty(&db, "src/a.py", "x", "int");

Ok(())
}

#[test]
fn resolve_unannotated_unbound_public() -> anyhow::Result<()> {
let mut db = setup_db();

db.write_dedented(
"src/a.py",
"
if flag:
x = 1
",
)?;

assert_public_ty(&db, "src/a.py", "x", "Literal[1]");

Ok(())
}

#[test]
fn literal_int_arithmetic() -> anyhow::Result<()> {
let mut db = setup_db();
Expand Down Expand Up @@ -5452,7 +5486,7 @@ mod tests {
// TODO: once we support `sys.version_info` branches,
// we can set `--target-version=py311` in this test
// and the inferred type will just be `BaseExceptionGroup` --Alex
assert_public_ty(&db, "src/a.py", "e", "Unknown | BaseExceptionGroup");
assert_public_ty(&db, "src/a.py", "e", "BaseExceptionGroup");

Ok(())
}
Expand All @@ -5478,7 +5512,7 @@ mod tests {
// and the inferred type will just be `BaseExceptionGroup` --Alex
//
// TODO more precise would be `ExceptionGroup[OSError]` --Alex
assert_public_ty(&db, "src/a.py", "e", "Unknown | BaseExceptionGroup");
assert_public_ty(&db, "src/a.py", "e", "BaseExceptionGroup");

Ok(())
}
Expand All @@ -5504,7 +5538,7 @@ mod tests {
// and the inferred type will just be `BaseExceptionGroup` --Alex
//
// TODO more precise would be `ExceptionGroup[TypeError | AttributeError]` --Alex
assert_public_ty(&db, "src/a.py", "e", "Unknown | BaseExceptionGroup");
assert_public_ty(&db, "src/a.py", "e", "BaseExceptionGroup");

Ok(())
}
Expand Down

0 comments on commit b67b0b3

Please sign in to comment.