python / python/mypy

[1.16 regression] Explicit type declaration overridden/merged with Any

Open
#19,034 3 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug topic-join-v-union
Dominant language
Python
Stars
20.6k
Forks
3.3k
PR merge metrics
PR metrics pending

Description

Bug Report

It appears that explicit type definitions of loop variables can be overridden or merged with values inferred from the iterator. Unfortunately this happens even when the iterator type is Any, somewhat undermining the explicit definition.

To Reproduce

import itertools, typing

class ErrorType:
    pass

def report_errors(error_type: ErrorType, id_: object, messages: list[str]) -> None:
    pass

errors: list[typing.Any]

source: tuple[ErrorType, object] | None
for source, errors_group in errors:
    reveal_type(source)  # good: Union[tuple[demo.ErrorType, builtins.object], None]
                         # bad: Union[tuple[demo.ErrorType, builtins.object], Any]
    if source:
        reveal_type(source)  # good: tuple[demo.ErrorType, builtins.object]
                             # bad: Union[tuple[demo.ErrorType, builtins.object], Any]

        messages: list[str]
        report_errors(*source, messages)  # bad: Too many arguments for "report_errors"

I've tried reproducing this without the loop, however that seems to make the issue go away.

Removing the messages argument to report_errors also seems to avoid the "too many arguments" error, though that doesn't affect the revealed types so I've left it in to give a clearer pass/fail when running mypy.

Expected Behavior

Under 1.15 and up to 8dd616b7d the above code passes cleanly with the "good" noted revealed types.

Actual Behavior

From b50f3a1a4 onwards the above code fails type checking due to the errant message to the report_errors function, and outputs the "bad" noted revealed types. I'm not familiar enough with mypy to explain why that commit is the cause, however I have narrowed this to that commit using git bisect so I'm fairly confident those changes are related.

Your Environment

Versions as noted above. No command line flags or other config needed.

Python 3.12.3 on Ubuntu 24.04.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by running the supplied Python reproducer with mypy and compare behavior around commits 8dd616b7d and b50f3a1a4. Trace the loop-variable type inference and explicit declaration handling implicated by the regression. Done means the reproducer passes again, with the reported reveal_type results and no erroneous argument-count error.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
compilers
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.