diff --git a/mypy/checkexpr.py b/mypy/checkexpr.py index c04f0bd2b4fa..dfd09f6ec705 100644 --- a/mypy/checkexpr.py +++ b/mypy/checkexpr.py @@ -1,6 +1,11 @@ """Expression type checker. This file is conceptually part of TypeChecker.""" from __future__ import annotations +<<<<<<< HEAD +======= + +from mypy.types import Instance, get_proper_type +>>>>>>> d76cb3e76 (Fix iterator element type extraction for yield from) import enum import itertools @@ -6273,7 +6278,13 @@ def visit_yield_from_expr(self, e: YieldFromExpr, allow_none_return: bool = Fals # Check that the iterator's item type matches the type yielded by the Generator function # containing this `yield from` expression. expected_item_type = self.chk.get_generator_yield_type(return_type, False) - actual_item_type = self.chk.get_generator_yield_type(iter_type, False) + + iter_type_proper = get_proper_type(iter_type) + + if isinstance(iter_type_proper, Instance) and iter_type_proper.args: + actual_item_type = iter_type_proper.args[0] + else: + actual_item_type = self.chk.get_generator_yield_type(iter_type, False) self.chk.check_subtype( actual_item_type, diff --git a/mypy/report.py b/mypy/report.py index 885d077d259e..42af8fc82854 100644 --- a/mypy/report.py +++ b/mypy/report.py @@ -147,7 +147,8 @@ def iterate_python_lines(path: str) -> Iterator[tuple[int, str]]: """Return an iterator over (line number, line text) from a Python file.""" if not os.path.isdir(path): # can happen with namespace packages with tokenize.open(path) as input_file: - yield from enumerate(input_file, 1) + for item in enumerate(input_file, 1): + yield item class FuncCounterVisitor(TraverserVisitor): diff --git a/test-data/unit/check-functions.test b/test-data/unit/check-functions.test index 699e83ccbd9f..37d596e86a8a 100644 --- a/test-data/unit/check-functions.test +++ b/test-data/unit/check-functions.test @@ -3768,3 +3768,14 @@ class C: def defer() -> int: return 1 + + +[case testYieldFromIteratorMismatch] +from typing import Generator, Iterator,Tuple + +class A(Iterator[int]): + def __next__(self) -> int: ... + def __iter__(self) -> "A": ... + +def f() -> Generator[Tuple[int, ...], None, None]: + yield from A() # E: Incompatible types in "yield"