microsoft/pyright

False positive of reportRedeclaration under conditional statement

Closed this issue · 1 comments

Describe the bug
A conditional declaration of wrapped function declaration is treated as double declaration, though that works well in runtime. Tested on the oldest possible version on pyright playground (1.1.341) and the newest (1.1.390).

Code or Screenshots

def f(toggle: bool) -> str | int:
    if toggle:
        def _f() -> str:
            return "1"
    else:
        def _f() -> int:
            return 1
    return _f()

This is by design. Pyright does not allow you to declare the same symbol in two different incompatible ways. In this case, _f has two incompatible declarations.

The fact that this works at runtime is irrelevant. I can provide many examples of code that doesn't crash at runtime but violates typing rules.

Here's a way to make this type check without errors.

def f(toggle: bool) -> str | int:
    if toggle:
        def _f1() -> str:
            return "1"
        f = _f1
    else:
        def _f2() -> int:
            return 1
        f = _f2
    return f()

Alternatively:

def f(toggle: bool) -> str | int:
    if toggle:
        def _f() -> str | int:
            return "1"
    else:
        def _f() -> str | int:
            return 1
    return _f()