microsoft / pyright

Static Type Checker for Python
Other
13.24k stars 1.43k forks source link

Type is not inferred for the long `match` statements #9214

Closed AlexanderPodorov closed 3 hours ago

AlexanderPodorov commented 3 hours ago

Describe the bug Possible regression caused by https://github.com/microsoft/pyright/issues/9146. Type is not inferred for the long match statements.

Code or Screenshots See the comments to the test function.

class A1:
    pass

class A2:
    pass

class A3:
    pass

class A4:
    pass

class A5:
    pass

class A6:
    pass

class A7:
    pass

class A8:
    pass

class A9:
    pass

class A10:
    pass

class A11:
    pass

class A12:
    pass

class A13:
    pass

class A14:
    pass

class A15:
    pass

class A16:
    pass

class B1:
    pass

class B2:
    pass

class B3:
    pass

class B4:
    pass

class B5:
    pass

class B6:
    pass

class B7:
    pass

class B8:
    pass

class B9:
    pass

class B10:
    pass

class B11:
    pass

class B12:
    pass

class B13:
    pass

class B14:
    pass

class B15:
    pass

class B16:
    pass

type UA = A1 | A2 | A3 | A4 | A5 | A6 | A7 | A8 | A9 | A10 | A11 | A12 | A13 | A14 | A15 | A16

type UB = B1 | B2 | B3 | B4 | B5 | B6 | B7 | B8 | B9 | B10 | B11 | B12 | B13 | B14 | B15 | B16

def f1(a: A1, b: B1) -> bool: ...

def f2(a: A2, b: B2) -> bool: ...

def f3(a: A3, b: B3) -> bool: ...

def f4(a: A4, b: B4) -> bool: ...

def f5(a: A5, b: B5) -> bool: ...

def f6(a: A6, b: B6) -> bool: ...

def f7(a: A7, b: B7) -> bool: ...

def f8(a: A8, b: B8) -> bool: ...

def f9(a: A9, b: B9) -> bool: ...

def f10(a: A10, b: B10) -> bool: ...

def f11(a: A11, b: B11) -> bool: ...

def f12(a: A12, b: B12) -> bool: ...

def f13(a: A13, b: B13) -> bool: ...

def f14(a: A14, b: B14) -> bool: ...

def f15(a: A15, b: B15) -> bool: ...

def f16(a: A16, b: B16) -> bool: ...

def test(a: UA, b: UB) -> bool:
    match a, b:
        case A1(), B1():
            return f1(a, b)  # passes
        case A2(), B2():
            return f2(a, b)  # passes
        case A3(), B3():
            return f3(a, b)  # passes
        case A4(), B4():
            return f4(a, b)  # passes
        case A5(), B5():
            return f5(a, b)  # passes
        case A6(), B6():
            return f6(a, b)  # passes
        case A7(), B7():
            return f7(a, b)  # passes
        case A8(), B8():
            return f8(a, b)  # passes
        case A9(), B9():
            return f9(a, b)  # "argument can not be assigned" warning
        case A10(), B10():
            return f10(a, b)  # "argument can not be assigned" warning
        case A11(), B11():
            return f11(a, b)  # "argument can not be assigned" warning
        case A12(), B12():
            return f12(a, b)  # "argument can not be assigned" warning
        case A13(), B13():
            return f13(a, b)  # "argument can not be assigned" warning
        case A14(), B14():
            return f14(a, b)  # "argument can not be assigned" warning
        case A15(), B15():
            return f15(a, b)  # "argument can not be assigned" warning
        case A16(), B16():
            return f16(a, b)  # "argument can not be assigned" warning
        case _:
            return False

VS Code extension or command-line Pylance v2024.10.100, Pyright 1.1.384.

erictraut commented 3 hours ago

Yes, this behavior is expected given the fix to the other issue you filed. Refer to this post for an explanation.

If you use this pattern, you can either have accurate type inference or reasonable performance. You can't have both.

erictraut commented 1 hour ago

As a workaround, you could do this:

        case A9() as x, B9() as y:
            return f9(x, y)