Skip to content

Commit 3c30736

Browse files
authored
Fix errors for raise NotImplemented (#20168)
See also discussion on python/typeshed#14966
1 parent 902acd1 commit 3c30736

File tree

4 files changed

+23
-9
lines changed

4 files changed

+23
-9
lines changed

mypy/checker.py

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,7 @@
198198
from mypy.types import (
199199
ANY_STRATEGY,
200200
MYPYC_NATIVE_INT_NAMES,
201+
NOT_IMPLEMENTED_TYPE_NAMES,
201202
OVERLOAD_NAMES,
202203
AnyType,
203204
BoolTypeQuery,
@@ -4974,10 +4975,7 @@ def check_return_stmt(self, s: ReturnStmt) -> None:
49744975
)
49754976
# Treat NotImplemented as having type Any, consistent with its
49764977
# definition in typeshed prior to python/typeshed#4222.
4977-
if (
4978-
isinstance(typ, Instance)
4979-
and typ.type.fullname == "builtins._NotImplementedType"
4980-
):
4978+
if isinstance(typ, Instance) and typ.type.fullname in NOT_IMPLEMENTED_TYPE_NAMES:
49814979
typ = AnyType(TypeOfAny.special_form)
49824980

49834981
if defn.is_async_generator:
@@ -5136,7 +5134,14 @@ def type_check_raise(self, e: Expression, s: RaiseStmt, optional: bool = False)
51365134
# https://github.com/python/mypy/issues/11089
51375135
self.expr_checker.check_call(typ, [], [], e)
51385136

5139-
if isinstance(typ, Instance) and typ.type.fullname == "builtins._NotImplementedType":
5137+
if (
5138+
isinstance(typ, Instance)
5139+
and typ.type.fullname in {"builtins._NotImplementedType", "types.NotImplementedType"}
5140+
) or (
5141+
isinstance(e, CallExpr)
5142+
and isinstance(e.callee, RefExpr)
5143+
and e.callee.fullname in {"builtins.NotImplemented"}
5144+
):
51405145
self.fail(
51415146
message_registry.INVALID_EXCEPTION.with_additional_msg(
51425147
'; did you mean "NotImplementedError"?'

mypy/types.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,8 @@
200200

201201
ELLIPSIS_TYPE_NAMES: Final = ("builtins.ellipsis", "types.EllipsisType")
202202

203+
NOT_IMPLEMENTED_TYPE_NAMES: Final = ("builtins._NotImplementedType", "types.NotImplementedType")
204+
203205
# A placeholder used for Bogus[...] parameters
204206
_dummy: Final[Any] = object()
205207

test-data/unit/check-statements.test

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -523,7 +523,7 @@ if object():
523523
if object():
524524
raise NotImplemented # E: Exception must be derived from BaseException; did you mean "NotImplementedError"?
525525
if object():
526-
raise NotImplemented() # E: NotImplemented? not callable
526+
raise NotImplemented() # E: Exception must be derived from BaseException; did you mean "NotImplementedError"?
527527
[builtins fixtures/notimplemented.pyi]
528528

529529
[case testTryFinallyStatement]

test-data/unit/fixtures/notimplemented.pyi

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,16 @@ class bool: pass
1010
class int: pass
1111
class str: pass
1212
class dict: pass
13+
class tuple: pass
14+
class ellipsis: pass
1315

14-
class _NotImplementedType(Any):
15-
__call__: NotImplemented # type: ignore
16-
NotImplemented: _NotImplementedType
16+
import sys
17+
18+
if sys.version_info >= (3, 10): # type: ignore
19+
from types import NotImplementedType
20+
NotImplemented: NotImplementedType
21+
else:
22+
class _NotImplementedType(Any): ...
23+
NotImplemented: _NotImplementedType
1724

1825
class BaseException: pass

0 commit comments

Comments
 (0)