Skip to content

Commit be1b921

Browse files
committed
Fix yield from semantics for AnyType
Revised version of someone else's PR that also should also avoid a crash when the type isn't some sort of Instance. Avoids cast using the now-possible `if not isinstance: return` construction.
1 parent 511f441 commit be1b921

File tree

2 files changed

+15
-3
lines changed

2 files changed

+15
-3
lines changed

mypy/checker.py

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1744,10 +1744,16 @@ def visit_call_expr(self, e: CallExpr) -> Type:
17441744
def visit_yield_from_expr(self, e: YieldFromExpr) -> Type:
17451745
# result = self.expr_checker.visit_yield_from_expr(e)
17461746
result = self.accept(e.expr)
1747-
result_instance = cast(Instance, result)
1748-
if result_instance.type.fullname() == "asyncio.futures.Future":
1747+
1748+
# If the yield-from isn't typechecked (ie, its Any), don't typecheck
1749+
if isinstance(result, AnyType):
1750+
return AnyType()
1751+
1752+
if not isinstance(result, Instance):
1753+
self.msg.yield_from_invalid_operand_type(e.expr.accept(self), e)
1754+
elif result.type.fullname() == "asyncio.futures.Future":
17491755
self.function_stack[-1].is_coroutine = True # Set the function as coroutine
1750-
result = result_instance.args[0] # Set the return type as the type inside
1756+
result = result.args[0] # Set the return type as the type inside
17511757
elif is_subtype(result, self.named_type('typing.Iterable')):
17521758
# TODO
17531759
# Check return type Iterator[Some]

mypy/test/data/check-statements.test

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -725,6 +725,12 @@ def g() -> Iterator[str]:
725725
yield "g2 more spam"
726726
[out]
727727

728+
[case testYieldFromAny]
729+
from typing import Iterator
730+
def f(a):
731+
b = yield from a
732+
return b
733+
[out]
728734

729735
-- With statement
730736
-- --------------

0 commit comments

Comments
 (0)