File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -1816,10 +1816,22 @@ def check_callable_call(
18161816
18171817 if (
18181818 callee .is_type_obj ()
1819- and ( len (arg_types ) == 1 )
1819+ and len (arg_types ) == 1
18201820 and is_equivalent (callee .ret_type , self .named_type ("builtins.type" ))
18211821 ):
1822- callee = callee .copy_modified (ret_type = TypeType .make_normalized (arg_types [0 ]))
1822+ proper_arg = get_proper_type (arg_types [0 ])
1823+ if isinstance (proper_arg , Instance ) and proper_arg .type .is_protocol :
1824+ callee = callee .copy_modified (
1825+ ret_type = UnionType (
1826+ [
1827+ self .named_type ("builtins.type" ),
1828+ self .named_type ("types.ModuleType" ),
1829+ AnyType (TypeOfAny .special_form ),
1830+ ]
1831+ )
1832+ )
1833+ else :
1834+ callee = callee .copy_modified (ret_type = TypeType .make_normalized (arg_types [0 ]))
18231835
18241836 if callable_node :
18251837 # Store the inferred callable type.
Original file line number Diff line number Diff line change @@ -4238,6 +4238,34 @@ def g4(a: Input[bytes], b: Output[str]) -> None:
42384238
42394239[builtins fixtures/tuple.pyi]
42404240
4241+ [case testTypeCallOnProtocol]
4242+ from typing import Any, Protocol, cast
4243+ import types
4244+
4245+ class P(Protocol):
4246+ def foo(self) -> None: ...
4247+
4248+ import mod
4249+
4250+ a: P = mod
4251+ value = type(a)
4252+ reveal_type(value) # N: Revealed type is "Union[builtins.type, types.ModuleType, Any]"
4253+ reveal_type(value.foo) # E: Item "type" of "Union[type, Module, Any]" has no attribute "foo" \
4254+ # N: Revealed type is "Any"
4255+
4256+ class Namespace: ...
4257+ n = Namespace()
4258+ n.foo = lambda: None # E: "Namespace" has no attribute "foo"
4259+
4260+ b: P = cast(Any, n)
4261+ value = type(b)
4262+ reveal_type(value) # N: Revealed type is "Union[builtins.type, types.ModuleType, Any]"
4263+ reveal_type(value.foo) # E: Item "type" of "Union[type, Module, Any]" has no attribute "foo" \
4264+ # N: Revealed type is "Any"
4265+ [file mod.py]
4266+ def foo() -> None: ...
4267+
4268+ [builtins fixtures/tuple.pyi]
42414269[case testOverloadProtocolSubtyping]
42424270from typing import Protocol, Self, overload
42434271
You can’t perform that action at this time.
0 commit comments