Skip to content

Commit b2f9432

Browse files
committed
Allow instantiating type[None] / types.NoneType
analyze_type_type_callee() had no case for mypy's internal NoneType, so calling a value of type type[None] (e.g. via type(None)() or a type[None]/type[types.NoneType] annotated callee) incorrectly produced a "Cannot instantiate type" error, even though this is valid at runtime and returns None. Fixes #19660
1 parent 630b101 commit b2f9432

2 files changed

Lines changed: 21 additions & 0 deletions

File tree

mypy/checkexpr.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1940,6 +1940,11 @@ def analyze_type_type_callee(self, item: ProperType, context: Context) -> Type:
19401940
"""
19411941
if isinstance(item, AnyType):
19421942
return AnyType(TypeOfAny.from_another_any, source_any=item)
1943+
if isinstance(item, NoneType):
1944+
# `type(None)` / `type[None]` is instantiable at runtime and returns None.
1945+
return CallableType(
1946+
[], [], [], NoneType(), self.named_type("builtins.function"), from_type_type=True
1947+
)
19431948
if isinstance(item, Instance):
19441949
res = type_object_type(item.type)
19451950
if isinstance(res, CallableType):

test-data/unit/check-classes.test

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3913,6 +3913,22 @@ def foo(arg: Type[Tuple[int]]):
39133913
arg() # E: Cannot instantiate type "type[tuple[int]]"
39143914
[builtins fixtures/tuple.pyi]
39153915

3916+
[case testTypeCanInstantiateNoneType]
3917+
from types import NoneType
3918+
3919+
type(None)()
3920+
NoneType()
3921+
3922+
def f(n: type[None]) -> None:
3923+
n()
3924+
3925+
def g(n: type[NoneType]) -> None: # E: NoneType should not be used as a type, please use None instead
3926+
n()
3927+
3928+
f(NoneType)
3929+
g(NoneType)
3930+
[builtins fixtures/tuple.pyi]
3931+
39163932
[case testTypeUsingTypeCOverloadedClass]
39173933
from foo import *
39183934
[file foo.pyi]

0 commit comments

Comments
 (0)