File tree Expand file tree Collapse file tree 2 files changed +25
-8
lines changed Expand file tree Collapse file tree 2 files changed +25
-8
lines changed Original file line number Diff line number Diff line change @@ -1807,8 +1807,15 @@ def check_callable_call(
18071807 ):
18081808 proper_arg = get_proper_type (arg_types [0 ])
18091809 if isinstance (proper_arg , Instance ) and proper_arg .type .is_protocol :
1810- self .msg .fail ("Calling type() on a protocol class is unsound" , context )
1811- callee = callee .copy_modified (ret_type = self .named_type ("builtins.object" ))
1810+ callee = callee .copy_modified (
1811+ ret_type = UnionType (
1812+ [
1813+ self .named_type ("builtins.type" ),
1814+ self .named_type ("types.ModuleType" ),
1815+ AnyType (TypeOfAny .special_form ),
1816+ ]
1817+ )
1818+ )
18121819 else :
18131820 callee = callee .copy_modified (ret_type = TypeType .make_normalized (arg_types [0 ]))
18141821
Original file line number Diff line number Diff line change @@ -4217,19 +4217,29 @@ def g4(a: Input[bytes], b: Output[str]) -> None:
42174217[builtins fixtures/tuple.pyi]
42184218
42194219[case testTypeCallOnProtocol]
4220- from typing import Protocol
4221-
4222- import mod
4220+ from typing import Any, Protocol, cast
4221+ import types
42234222
42244223class P(Protocol):
42254224 def foo(self) -> None: ...
42264225
4226+ import mod
4227+
42274228a: P = mod
4228- value = type(a) # E: Calling type() on a protocol class is unsound
4229- reveal_type(value) # N: Revealed type is "builtins.object "
4230- reveal_type(value.foo) # E: "object " has no attribute "foo" \
4229+ value = type(a)
4230+ reveal_type(value) # N: Revealed type is "Union[ builtins.type, types.ModuleType, Any] "
4231+ reveal_type(value.foo) # E: Item "type" of "Union[type, Module, Any] " has no attribute "foo" \
42314232 # N: Revealed type is "Any"
42324233
4234+ class Namespace: ...
4235+ n = Namespace()
4236+ n.foo = lambda: None # E: "Namespace" has no attribute "foo"
4237+
4238+ b: P = cast(Any, n)
4239+ value = type(b)
4240+ reveal_type(value) # N: Revealed type is "Union[builtins.type, types.ModuleType, Any]"
4241+ reveal_type(value.foo) # E: Item "type" of "Union[type, Module, Any]" has no attribute "foo" \
4242+ # N: Revealed type is "Any"
42334243[file mod.py]
42344244def foo() -> None: ...
42354245
You can’t perform that action at this time.
0 commit comments