Skip to content

inconsistent-overload false positives with Unpack[TypedDict] #3566

@dangotbanned

Description

@dangotbanned

Describe the Bug

pyrefly reports inconsistent-overload for every overload.

But pyright, mypy and ty 1 accept them:

Show code

from typing import *


class A: ...
class B: ...
class C(Protocol):
    def member(self) -> str: ...

T = TypeVar("T")

class ExcludeC(TypedDict, total=False):
    pass_through: bool
    only_a: bool
    only_c: Literal[False]
    include_c: Literal[False] | None

class OnlyC(TypedDict, total=False):
    pass_through: bool
    only_a: bool
    only_c: Required[Literal[True]]
    include_c: bool | None

class IncludeC(TypedDict, total=False):
    pass_through: bool
    only_a: bool
    only_c: Literal[False]
    include_c: Required[Literal[True]]

class IncludeB(TypedDict, total=False):
    pass_through: bool
    only_a: Literal[False]
    only_c: Literal[False]
    include_c: bool | None

class IncludeABC(TypedDict, total=False):
    pass_through: bool
    only_a: Literal[False]
    only_c: Literal[False]
    include_c: Required[Literal[True]]

class PassThrough(TypedDict, total=False):
    pass_through: Required[Literal[True]]
    only_a: bool
    only_c: bool
    include_c: bool | None


@overload
def func(obj: A, **kwds: Unpack[ExcludeC]) -> A: ...
@overload
def func(obj: C, **kwds: Unpack[OnlyC]) -> C: ...
@overload
def func(obj: C, **kwds: Unpack[IncludeC]) -> C: ...
@overload
def func(obj: B, **kwds: Unpack[IncludeB]) -> B: ...
@overload
def func(obj: A | C, **kwds: Unpack[IncludeC]) -> A | C: ...
@overload
def func(obj: A | B | C, **kwds: Unpack[IncludeABC]) -> A | B | C: ...
@overload
def func(obj: T, **kwds: Unpack[PassThrough]) -> T: ...
def func(
    obj: A | B | C | T,
    *,
    pass_through: bool = False,
    only_a: bool = False,
    only_c: bool = False,
    include_c: bool | None = None,
) -> A | B | C | T:
    raise NotImplementedError

That example is a minimized version of narwhals.from_native:

If there is an issue, the diagnostic should point towards what is missing.
The current output is 1x of these per overload 😳:

Implementation signature

(obj: A | B | C | T, *, pass_through: bool = False, only_a: bool = False, only_c: bool = False, include_c: bool | None = None) -> A | B | C | T

does not accept all arguments that overload signature

(obj: A, **kwds: Unpack[ExcludeC]) -> A accepts [inconsistent-overload]

Sandbox Link

https://pyrefly.org/sandbox/?project=N4IgZglgNgpgziAXKOBDAdgEwEYHsAeAdAA4CeS4ATrgLYAEALqcROgOZ0Q3G6UN0AqADroRIgMZRUcOHQCCiOoWVjR6SdNkAhRcsKqJUmXQDCACgAK1BrnG4oASkQi6ruphhg6NGDWwxKMzgYKDAHOgBaAD46OAZKXRU1EQAVOgBeOhTmGAA1VEChEBSihwN1I1kAUXxJAFcPc2ziGEwAEQhxBgAaRlwGVCh0gDFB4KcXN2JNAH0GAAtqOrZ5xTx7SddcdChSGdQ13A30Nzpt3ZnxRQAZCAYAwYBtUahggF1NzgqGmEubu4eUGeYxgbzoAB86AA5bYwcoaYwAeR2pCaOXanR6fQGQxe42cJymswWSxWh2Op3OewOdHWUE%2BVL%2BdAASjAAI51CCUVqPW73ShPFKUOqgj6E1yseoeJl0iHQ2Hwyp0ACS30aZmarQ6XV6NhxIxBE3FdGmMjmi1wy1WtKO9ONjJpdIZKKZfMBwNeoM%2BkqgPyZrI5XJ5boFQKFIreYtUCNkqqlMC0GvR2qxesGBs9RtOprg5tJ1qd9pdNJDTzxXqLFyudFLQPLYtOPr91dlkJh6DhyQqmhVapgci0aJaGJ12PT5azRLNJMtZJtFLcDv%2B-LLIIbi5d1drHve3r7-vZnO5mF5ANDj3DosVPYsmhSFqtSeHKd1-XHhoJ2eJD7nAaPwbPQVhSvStqXJO1KU3cC93jGVbTldtO1UAABXAADcAigXBUEwEQPC8MA6nUMxcGwAArRQ5F6AQBAAawAd0wOBFAAVXQaZxFox4anjEw3nCaJ5ESfR0FQjDKCwnC8M8OhCOI0iKNMai6MY5i6DYjiuORXY%2BIEmITGEkQxMw7DcKwGS5PEEjyMUExlIYpjWPY1BOMeONfUafjIn0wzRPQkypPMgiiKshTFC0ezVKczS3L7LQvMEnQlCSYyJNM6Tgvkmz5DlOzBBUxz1Oc1z3J%2BXTvJyyEDOSkTUsksz8NkkLrMUuQ5S0XLIsKjSXK40qPAHcrBLayEOqq3y6vSoKmqyxSUi6tSetc28ZHvfMEpiFJfMayyzAZbKRroMbTDlebPgEbpPhzPNZwLeDMnLS7QP2cCMjoR7nSrV6HpBJ7G33Ft4LbWE3sQp69Mqo7ctOz83AFCBgnlBhlW4WAfHQe5MCqShqEoEQQG6EAyG5MBdkIGwaCgCgAGI6AsUgSd2WIMBwAg6DsdBIDYOoBQYCBthE2mAGUYBgOh5gYBhiGYgB6GXic8MneDYGWYHQGXMFsOAZY5rmedQPnthl2TeDoVA0NQaBUGwWB2e2PXef5k5cGIQ30DgESyAWbYInEuAnbeooAGZCAARgAJiKERHgCXG4DFIiuB4PhWgiTAgy6CAMLegByCA2HQXgYBzkRC4YCJuUDY8IlomBSAiFzxHgWRMhz%2BiCnQEv0BAABfQmXL5jDhmgGAKDQLA8CIMhe6AA

(Only applicable for extension issues) IDE Information

No response

Footnotes

  1. I've included ty for completeness, but I think it is missing support for at least 1 feature here

Metadata

Metadata

Assignees

Labels

needs-discussionAn issue where it's not clear whether there is a bug or we are behaving as expected.typechecking

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions