From b2f94324eb16fd109512ad5f3f9ee66f7cfd8582 Mon Sep 17 00:00:00 2001 From: mmaxjr Date: Sun, 2 Aug 2026 10:00:59 -0300 Subject: [PATCH] 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 --- mypy/checkexpr.py | 5 +++++ test-data/unit/check-classes.test | 16 ++++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/mypy/checkexpr.py b/mypy/checkexpr.py index 172d44555b946..26ba319d7aa5e 100644 --- a/mypy/checkexpr.py +++ b/mypy/checkexpr.py @@ -1940,6 +1940,11 @@ def analyze_type_type_callee(self, item: ProperType, context: Context) -> Type: """ if isinstance(item, AnyType): return AnyType(TypeOfAny.from_another_any, source_any=item) + if isinstance(item, NoneType): + # `type(None)` / `type[None]` is instantiable at runtime and returns None. + return CallableType( + [], [], [], NoneType(), self.named_type("builtins.function"), from_type_type=True + ) if isinstance(item, Instance): res = type_object_type(item.type) if isinstance(res, CallableType): diff --git a/test-data/unit/check-classes.test b/test-data/unit/check-classes.test index 2cd43c74ebb5b..a52dc0c882089 100644 --- a/test-data/unit/check-classes.test +++ b/test-data/unit/check-classes.test @@ -3913,6 +3913,22 @@ def foo(arg: Type[Tuple[int]]): arg() # E: Cannot instantiate type "type[tuple[int]]" [builtins fixtures/tuple.pyi] +[case testTypeCanInstantiateNoneType] +from types import NoneType + +type(None)() +NoneType() + +def f(n: type[None]) -> None: + n() + +def g(n: type[NoneType]) -> None: # E: NoneType should not be used as a type, please use None instead + n() + +f(NoneType) +g(NoneType) +[builtins fixtures/tuple.pyi] + [case testTypeUsingTypeCOverloadedClass] from foo import * [file foo.pyi]