Skip to content

(*args: Any, **kwargs: Any) not treated as equivalent to gradual signature ... #1837

@randolf-scholz

Description

@randolf-scholz

Describe the Bug

According to the typing spec

If the input signature in a function definition includes both a *args and **kwargs parameter and both are typed as Any (explicitly or implicitly because it has no annotation), a type checker should treat this as the equivalent of .... Any other parameters in the signature are unaffected and are retained as part of the signature

The example from the spec, copy-pasted into sandbox, gives 4 false positives

from typing import Any, Protocol, assert_type, Concatenate, Callable

class Proto1(Protocol):
    def __call__(self, *args: Any, **kwargs: Any) -> None: ...

class Proto2(Protocol):
    def __call__(self, a: int, /, *args, **kwargs) -> None: ...

class Proto3(Protocol):
    def __call__(self, a: int, *args: Any, **kwargs: Any) -> None: ...

class Proto4[**P](Protocol):
    def __call__(self, a: int, *args: P.args, **kwargs: P.kwargs) -> None: ...

def func(p1: Proto1, p2: Proto2, p3: Proto3) -> None:
    assert_type(p1, Callable[..., None])                    # Spec: ✅️ pyrefly: ❌️
    assert_type(p2, Callable[Concatenate[int, ...], None])  # Spec: ✅️ pyrefly: ❌️ 
    assert_type(p3, Callable[..., None])                    # Spec: ❌️ pyrefly: ❌️
    assert_type(p3, Proto4[...])                            # Spec: ✅️ pyrefly: ❌️

class A:
    def method(self, a: int, /, *args: Any, k: str, **kwargs: Any) -> None:
        pass

class B(A):
    # This override is OK because it is assignable to the parent's method.
    # Spec: ✅️ pyrefly: ❌️
    def method(self, a: float, /, b: int, *, k: str, m: str) -> None:
        pass

Sandbox Link

https://pyrefly.org/sandbox/?project=N4IgZglgNgpgziAXKOBDAdgEwEYHsAeAdAA4CeS4ATrgLYAEALqcROgOZ0Q3G6UN0BBdKQA0dAArUGuAMa4oY1HDgw%2BAfSbEYYgMK50M1Axjoj2ujtRQoqbLAA66RzJvKJU3AEYAFJNzS5KABKREc6cLpMGDA6NTVDazjvFSgwMQAqVEo2OERBYQz0gGsAdyycvKFSILoAWgA%2BOgA5fRg8wg7HZ1c4d39cACZfD0CQsIiomLiEqCSUtLpUPNYGMQB6DPK4QtKtmobm1vbOpwMevukAZmH%2B0dD0CMjo2PirWbVkmFTFZfRVuky2Vy%2BVEAOKZSBlWE%2B0aLXQbToHUIXTOSl6fmkABYANrpdLiAC6NwC8jGDwmz2mbzmXwWS04f02kIkhC2OwhFRZuyBMMO8OOyNOkzoYAArgZvMRPHkMV4xMQBjKPAN5Zclf1Lry4W1xuE0aoGBpmDBJZ5dG9bLBsUixNqCTVHo6nY8AMR0ADKWhkeUAoOSAeD%2B6GRKNEoKQ8oAZcj9usWygNRq0kpVFgtdhg2L0BjMpmM2JWYiRBNtrXt4Tdnpg3ro-sDpGDYFDEYD0f16k0JuIl3N1ktaZtfJgJedQ9dHq9jZrdYbdEjzdjreNks7F1wOILDuHG%2BdZbHVYDQZDYenUdOLjRgnuj2FNBgDAAFrhMJ9votfv8NgCtlDQUU8nAGJR2U-EEtSOaNHmINEUVPNwACFvAEMkRwAFVvCBelwAA3VRKAgKJOF6AB5ABpOhsArVBRRUTh%2BDQmM4AgNhTFTRhcEYW8YEDLITAYAByXprzvB9BRHctK2rfd60PGdyXCK8b3vR95h%2BEUoFwIx1jEbBXwyMQfzoP8ALoGhf3-ED%2BTAiIIOUEARBAUUGGgOASHIRAQDdABVByoAgJgRXFGQHP0OAUWFMBeBoIw1HQUUaDIyhvHwV9eQMi8ImDBhRUoB4wHsEAmhiuK8mAfAAF9cscGyQAk0NCGkGgoAoN1xFrA99IwHACDoOR0EgNhMqMCB9EFMsYA428GAYYhcjWNZqtIQheDYNYTDWTBZDgNZut6-rAvQNYRV4RYMNQaAey6-RtsoAb9DoXBiF2pzHDIQT0FqLDKHom6AF46Fyy5CE8AZyvQEASts1AAogLCADFoBgCg0CwPAiDIUGgA

(Only applicable for extension issues) IDE Information

No response

Metadata

Metadata

Assignees

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions