[red-knot] Type narrowing for isinstance checks (#13894)

## Summary

Add type narrowing for `isinstance(object, classinfo)` [1] checks:
```py
x = 1 if flag else "a"

if isinstance(x, int):
    reveal_type(x)  # revealed: Literal[1]
```

closes #13893

[1] https://docs.python.org/3/library/functions.html#isinstance

## Test Plan

New Markdown-based tests in `narrow/isinstance.md`.

---------

Co-authored-by: Alex Waygood <Alex.Waygood@Gmail.com>
This commit is contained in:
David Peter 2024-10-23 20:51:33 +02:00 committed by GitHub
parent 72c18c8225
commit 2c57c2dc8a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 241 additions and 12 deletions

View file

@ -47,7 +47,13 @@ impl<'db> Definition<'db> {
self.kind(db).category().is_binding()
}
/// Return true if this is a symbol was defined in the `typing` or `typing_extensions` modules
pub(crate) fn is_builtin_definition(self, db: &'db dyn Db) -> bool {
file_to_module(db, self.file(db)).is_some_and(|module| {
module.search_path().is_standard_library() && matches!(&**module.name(), "builtins")
})
}
/// Return true if this symbol was defined in the `typing` or `typing_extensions` modules
pub(crate) fn is_typing_definition(self, db: &'db dyn Db) -> bool {
file_to_module(db, self.file(db)).is_some_and(|module| {
module.search_path().is_standard_library()