Skip to content

Commit 638dc62

Browse files
ilevkivskyiJukkaL
authored andcommitted
Fix crashes on lambda generators (#3523)
This fixes #3243 and similar crashes on lambda generators. Solution is straightforward: push return type (if known, or Any otherwise) same as we do for normal functions.
1 parent bc864c5 commit 638dc62

File tree

2 files changed

+19
-0
lines changed

2 files changed

+19
-0
lines changed

mypy/checkexpr.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1936,12 +1936,15 @@ def visit_lambda_expr(self, e: LambdaExpr) -> Type:
19361936
"""Type check lambda expression."""
19371937
inferred_type, type_override = self.infer_lambda_type_using_context(e)
19381938
if not inferred_type:
1939+
self.chk.return_types.append(AnyType())
19391940
# No useful type context.
19401941
ret_type = self.accept(e.expr(), allow_none_return=True)
19411942
fallback = self.named_type('builtins.function')
1943+
self.chk.return_types.pop()
19421944
return callable_type(e, fallback, ret_type)
19431945
else:
19441946
# Type context available.
1947+
self.chk.return_types.append(inferred_type.ret_type)
19451948
self.chk.check_func_item(e, type_override=type_override)
19461949
if e.expr() not in self.chk.type_map:
19471950
self.accept(e.expr(), allow_none_return=True)
@@ -1950,7 +1953,9 @@ def visit_lambda_expr(self, e: LambdaExpr) -> Type:
19501953
# For "lambda ...: None", just use type from the context.
19511954
# Important when the context is Callable[..., None] which
19521955
# really means Void. See #1425.
1956+
self.chk.return_types.pop()
19531957
return inferred_type
1958+
self.chk.return_types.pop()
19541959
return replace_callable_return_type(inferred_type, ret_type)
19551960

19561961
def infer_lambda_type_using_context(self, e: LambdaExpr) -> Tuple[Optional[CallableType],

test-data/unit/check-expressions.test

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1208,6 +1208,20 @@ def void() -> None:
12081208
pass
12091209
x = lambda: void() # type: typing.Callable[[], None]
12101210

1211+
[case testNoCrashOnLambdaGenerator]
1212+
from typing import Iterator, Callable
1213+
1214+
# These should not crash
1215+
lambda: (yield)
1216+
1217+
gen: Callable[[], Iterator[str]]
1218+
gen = (lambda: (yield 1)) # E: Incompatible types in yield (actual type "int", expected type "str")
1219+
1220+
def fun(cb: Callable[[], Iterator[str]]) -> None:
1221+
pass
1222+
fun(lambda: (yield from [1])) # E: Incompatible types in "yield from" (actual type "int", expected type "str")
1223+
[builtins fixtures/list.pyi]
1224+
[out]
12111225

12121226
-- List comprehensions
12131227
-- -------------------

0 commit comments

Comments
 (0)