Skip to content

isinstance() narrowing breaks after unrelated isinstance() check in a returning sibling branch (1.1.0 regression) #3867

Description

@friday

Describe the Bug

isinstance() narrowing of a union variable silently stops working when an earlier sibling branch in the same if/elif/else chain narrows a different variable with isinstance() and returns. The later narrowing leaves the union untouched, producing false missing-attribute errors.

This is a regression: it works correctly in pyrefly 1.0.0 and is broken in 1.1.0 (git bisect came up with 86f0da7 being the culprit).

Inside if isinstance(value, int):, value should narrow to int, as it does in 1.0.0. The isinstance(other, int) check on the unrelated other in the earlier elif should have no effect on value.

Repro

(same as sandbox link)

from typing import reveal_type

def f(cond: bool, other: object, value: int | str) -> None:
    if cond:
        pass
    elif isinstance(other, int):   # narrows a DIFFERENT variable, in a branch that returns
        return
    else:
        return

    reveal_type(value)             # int | str
    if isinstance(value, int):
        reveal_type(value)         # BUG: int | str   (should be: int)
        value.bit_length()         # false error: `str` has no attribute `bit_length`

Expected / 1.0.0 behavior

revealed type: int | str
revealed type: int
0 errors

Actual behavior

revealed type: int | str
revealed type: int | str        <- should be `int`
ERROR Object of class `str` has no attribute `bit_length` [missing-attribute]

Sandbox Link

https://pyrefly.org/sandbox/?project=N4IgZglgNgpgziAXKOBDAdgEwEYHsAeAdAA4CeS4ATrgLYAEALqcROgOZ0Q3G6UN2UYANxiooAfSbEYAHXRzMMMHTAAKAMa4siOnlxQANHVwMAFjEo7c2AFYx1DI0LEBXGDtb8APnTgNKAJR0ALQAfHQAclrucnRxnMqa2rHxqcSocHApcTBQEMoQcKx%2BGOowqibmlEaeATpxAMR06KiU1ADucHSodAAiAJIAYoMAogBKIxEAKnTOlBCo2LA16N26lKWmjKao-IIMLpToWaup8fuH8qc5UHAx12cXR3LZAsKiElLlzlBuQWcAuhNTx0Hx%2BSivfKcIrHBilb6uGArBh1V6pQQiMSSZgI34wf6ApoAIQAqgBxDzoby%2BfzxVRwUy4FxQTC6dycKkBNHxH5uQjYCAMcSwdhmVQEgFNMBiO50CzUSx0AAG4KVdB2XXQuG6DH8EGwLgYMGVAqFIrYZiVIAMIDIgjAUFIhAYtCgFCaAAVSPbHb4MDgCHQkpA2IddhAtIQ5E0AMowY2mXXEOCIAD0qbtSkdhF4bFTMHQqcwuHUcFTwYgoY2DAjhZUvG6zmgi1gQa0IbDNa0xmIXeOUfQIAAvjbUA4ICJBtAYBQ0Fg8EQyMOgA

(Only applicable for extension issues) IDE Information

No response

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

Fields

No fields configured for Bug.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions