Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork3k
Open
Description
According to the typing spec (https://typing.python.org/en/latest/spec/callables.html#meaning-of-in-callable),
@runtime_checkableclassAnyCallable(Protocol):def__call__(self,*args:Any,**kwargs:Any)->Any: ...
is an implementation ofCallable[..., Any]
. Therefore, itsisinstance
-narrowing and match-case class pattern narrowing should behave the same as a simpleif callable()
narrowing. However, this is not the case: bothisinstance
andmatch-case
produce different results:
fromtypingimportAny,Callablefromtyping_extensionsimportProtocol,runtime_checkable,assert_type@runtime_checkableclassAnyCallable(Protocol):def__call__(self,*args:Any,**kwargs:Any)->Any: ...defcheck_proto(p:AnyCallable)->None:assert_type(p,Callable[...,Any])classFnImpl:def__call__(self,x:object,/)->int: ...# Test Baselinedeftest_iscallable_object(x:object)->None:ifcallable(x):reveal_type(x)# N: Revealed type is "__main__.<callable subtype of object>"deftest_iscallable_impl(x:FnImpl)->None:ifcallable(x):reveal_type(x)# N: Revealed type is "__main__.FnImpl"deftest_iscallable_callable(x:Callable[[object],int])->None:ifcallable(x):reveal_type(x)# N: Revealed type is "def (builtins.object) -> builtins.int"# Test isinstancedeftest_isinstance_object(x:object)->None:ifisinstance(x,AnyCallable):reveal_type(x)# N: Revealed type is "__main__.AnyCallable"deftest_isinstance_impl(x:FnImpl)->None:ifisinstance(x,AnyCallable):reveal_type(x)# N: Revealed type is "__main__.FnImpl"deftest_isinstance_callable(x:Callable[[object],int])->None:ifisinstance(x,AnyCallable):reveal_type(x)# N: Revealed type is "__main__.AnyCallable"# test match-casedeftest_match_object(x:object)->None:matchx:caseAnyCallable()asfn:reveal_type(fn)# N: Revealed type is "__main__.AnyCallable"deftest_match_impl(x:FnImpl)->None:matchx:caseAnyCallable()asfn:reveal_type(fn)# N: Revealed type is "__main__.AnyCallable"deftest_match_callable(x:Callable[[object],int])->None:matchx:caseAnyCallable()asfn:reveal_type(fn)# N: Revealed type is "__main__.AnyCallable"
https://mypy-play.net/?mypy=latest&python=3.12&gist=5cb05553fa6674d445906eda99802e90