Skip to content

Should callable narrow to TypeIs[Callable[..., object]] or TypeIs[Callable] ? #16050

Description

@randolf-scholz

Currently, typeshed annotates

def callable(obj: object, /) -> TypeIs[Callable[..., object]]: ...

However, for the majority of type checkers this creates discrepancy between collections.abc.Callable and builtins.callable narrowing, only ty seems to consider blank Callable as if it were Callable[..., object], whereas all other type checkers treat it as Callable[..., Any].

from typing import reveal_type, TypeIs
from collections.abc import Callable

def is_callable(arg: object) -> TypeIs[Callable]:
    raise NotImplementedError

def check_callable(arg: object) -> None:
    if isinstance(arg, Callable):
        reveal_type(arg)
            
def check_callable2(arg: object) -> None:
    if callable(arg):
        reveal_type(arg)
        
def check_callable3(arg: object) -> None:
    if is_callable(arg):
        reveal_type(arg)
case isinstance(x, Callable) is_callable callable(x)
mypy ERROR (...) -> Any <callable subtype of object>
pyright (...) -> Unknown (...) -> Unknown (...) -> object
pyrefly (...) -> Unknown (...) -> Unknown (...) -> object
ty (...) -> object (...) -> Any (...) -> object
zuban ERROR (...) -> Any <callable subtype of object>

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Fields

    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