Skip to content

Commit 49d5cc9

Browse files
authored
Ensure instances of CallableType can always be hashed (#12741)
1 parent 23e2a51 commit 49d5cc9

File tree

2 files changed

+18
-2
lines changed

2 files changed

+18
-2
lines changed

mypy/types.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
import mypy.nodes
1515
from mypy.state import state
1616
from mypy.nodes import (
17-
INVARIANT, SymbolNode, FuncDef,
17+
INVARIANT, SymbolNode, FuncDef, FakeInfo,
1818
ArgKind, ARG_POS, ARG_STAR, ARG_STAR2,
1919
)
2020
from mypy.util import IdMapper
@@ -1766,7 +1766,12 @@ def expand_param_spec(self,
17661766
variables=[*variables, *self.variables])
17671767

17681768
def __hash__(self) -> int:
1769-
return hash((self.ret_type, self.is_type_obj(),
1769+
# self.is_type_obj() will fail if self.fallback.type is a FakeInfo
1770+
if isinstance(self.fallback.type, FakeInfo):
1771+
is_type_obj = 2
1772+
else:
1773+
is_type_obj = self.is_type_obj()
1774+
return hash((self.ret_type, is_type_obj,
17701775
self.is_ellipsis_args, self.name,
17711776
tuple(self.arg_types), tuple(self.arg_names), tuple(self.arg_kinds)))
17721777

test-data/unit/check-typeddict.test

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,17 @@ reveal_type(d) # N: Revealed type is "TypedDict('__main__.D', {'y': builtins.in
221221
[builtins fixtures/dict.pyi]
222222
[typing fixtures/typing-typeddict.pyi]
223223

224+
[case testTypedDictWithClassmethodAlternativeConstructorDoesNotCrash]
225+
# https://github.com/python/mypy/issues/5653
226+
from typing import TypedDict
227+
228+
class Foo(TypedDict):
229+
bar: str
230+
@classmethod # E: Invalid statement in TypedDict definition; expected "field_name: field_type"
231+
def baz(cls) -> "Foo": ...
232+
[builtins fixtures/dict.pyi]
233+
[typing fixtures/typing-typeddict.pyi]
234+
224235
[case testCanCreateTypedDictTypeWithUnderscoreItemName]
225236
from mypy_extensions import TypedDict
226237
Point = TypedDict('Point', {'x': int, 'y': int, '_fallback': object})

0 commit comments

Comments
 (0)