Skip to content

Wrong checking of overload for keyword-only args #1907

Closed
@dmoisset

Description

@dmoisset

While writing some stubs I found an issue that I simplified to the following:

from typing import overload

@overload
def f(*, out: str, flag: bool=False) -> str: ...

@overload
def f(*, flag: bool=False) -> bool: ...

reveal_type(f())  # I expect bool, get Any
reveal_type(f(flag=False))  # I expect bool, get Any
reveal_type(f(out="xxx"))   # I expect str, get str

The checker shows a

error: Overloaded function signatures 1 and 2 overlap with incompatible return types

but actually the signatures do not overlap (there's no call that can match both the signatures).

Something that's also confusing is that if I change the order of the arguments like this

# Move the "out" argument to the end
@overload
def f(*, flag: bool=False, out: str) -> str: ...
@overload
def f(*, flag: bool=False) -> bool: ...

I stop getting the "signature overlap" error, but I still get the "Any" type on the first two example calls. Given that these arguments are keyword only their positions shouldn't matter at all

(Comes from python/typing#248 )

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions