From 64f88feb9591a7c6a3188602c432a7a11539f646 Mon Sep 17 00:00:00 2001 From: freddyuniverse <122599255+freddyuniverse@users.noreply.github.com> Date: Wed, 21 Oct 2026 17:19:17 -0700 Subject: [PATCH] Report comprehension index errors at the index variable Errors from assigning a comprehension's item type to its index variable, such as "Need type annotation" or unpacking errors, were reported at the start of the whole comprehension. For multi-line comprehensions this pointed at the wrong line, and for generator expressions the line also depended on which parser was used. Use the index expression as the error context instead, so the error lands on the `for ... in ...` clause that defines the variable. Fixes #22265. --- mypy/checkexpr.py | 2 +- test-data/unit/check-inference.test | 60 +++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+), 1 deletion(-) diff --git a/mypy/checkexpr.py b/mypy/checkexpr.py index 52a3affa81a9..f002f8216add 100644 --- a/mypy/checkexpr.py +++ b/mypy/checkexpr.py @@ -6133,7 +6133,7 @@ def check_for_comp(self, e: GeneratorExpr | DictionaryComprehension) -> None: # To preserve backward compatibility, avoid inferring Never for "_" sequence_type = AnyType(TypeOfAny.special_form) - self.chk.analyze_index_variables(index, sequence_type, True, e) + self.chk.analyze_index_variables(index, sequence_type, True, index) for condition in conditions: self.accept(condition) diff --git a/test-data/unit/check-inference.test b/test-data/unit/check-inference.test index 05a4d5ece3d7..4504790ee667 100644 --- a/test-data/unit/check-inference.test +++ b/test-data/unit/check-inference.test @@ -1177,6 +1177,66 @@ for e, f in [[]]: # E: Need type annotation for "e" \ [builtins fixtures/for.pyi] +[case testInferenceOfIndexInMultiLineComprehension] +def f(x: object) -> None: pass + +f( + y + for y in [] # E: Need type annotation for "y" +) +a = [ + y + for y in [] # E: Need type annotation for "y" +] +b = { + y + for y in [] # E: Need type annotation for "y" +} +c = { + k: 0 + for k in [] # E: Need type annotation for "k" +} +d = [ + (y, z) + for y in [1] + for z in [] # E: Need type annotation for "z" +] +e = [ + y + for y, z in [(1, 2, 3)] # E: Too many values to unpack (2 expected, 3 provided) +] +[builtins fixtures/primitives.pyi] + +[case testInferenceOfIndexInMultiLineComprehension_old_parser] +def f(x: object) -> None: pass + +f( + y + for y in [] # E: Need type annotation for "y" +) +a = [ + y + for y in [] # E: Need type annotation for "y" +] +b = { + y + for y in [] # E: Need type annotation for "y" +} +c = { + k: 0 + for k in [] # E: Need type annotation for "k" +} +d = [ + (y, z) + for y in [1] + for z in [] # E: Need type annotation for "z" +] +e = [ + y + for y, z in [(1, 2, 3)] # E: Too many values to unpack (2 expected, 3 provided) +] +[builtins fixtures/primitives.pyi] + [case testForStatementInferenceWithVoid] def f() -> None: pass