[ty] Reachability analysis for isinstance(…) branches by sharkdp · Pull Request #19503 · astral-sh/ruff (original) (raw)

@sharkdp

sharkdp

sharkdp

@sharkdp sharkdp changed the title[ty] Type inference for isinstance(…) calls [ty] Reachability analysis for isinstance(…) branches

Jul 23, 2025

@sharkdp sharkdp marked this pull request as ready for review

July 23, 2025 09:19

AlexWaygood

@sharkdp

AlexWaygood

@sharkdp

@sharkdp sharkdp deleted the david/isinstance-inference branch

July 23, 2025 11:06

UnboundVariable pushed a commit to UnboundVariable/ruff that referenced this pull request

Jul 23, 2025

Conflicts:

crates/ty_ide/src/goto.rs

dcreager added a commit that referenced this pull request

Jul 23, 2025

@dcreager

AlexWaygood pushed a commit that referenced this pull request

Jul 25, 2025

@sharkdp @AlexWaygood

Summary

Add more precise type inference for a limited set of isinstance(…) calls, i.e. return Literal[True] if we can be sure that this is the correct result. This improves exhaustiveness checking / reachability analysis for if-elif-else chains with isinstance checks. For example:

def is_number(x: int | str) -> bool:  # no "can implicitly return `None` error here anymore
    if isinstance(x, int):
        return True
    elif isinstance(x, str):
        return False

    # code here is now detected as being unreachable

This PR also adds a new test suite for exhaustiveness checking.

Test Plan

New Markdown tests

Ecosystem analysis

The removed diagnostics look good. There's one case where a "true positive" is removed in unreachable code. src is annotated as being of type str, but there is an elif isinstance(src, bytes) branch, which we now detect as unreachable. And so the diagnostic inside that branch is silenced. I don't think this is a problem, especially once we have a "graying out" feature, or a lint that warns about unreachable code.

This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.Learn more about bidirectional Unicode characters

[ Show hidden characters]({{ revealButtonHref }})