Skip to content

Commit 06a4165

Browse files
committed
.
1 parent dec6528 commit 06a4165

2 files changed

Lines changed: 42 additions & 2 deletions

File tree

mypy/checkexpr.py

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff 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.

test-data/unit/check-protocols.test

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff 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]
42424270
from typing import Protocol, Self, overload
42434271

0 commit comments

Comments
 (0)