Skip to content

Fix union fallback skipped for assignments with ternary expressions (#21273)#21293

Open
armorbreak001 wants to merge 1 commit intopython:masterfrom
armorbreak001:fix/ternary-union-fallback
Open

Fix union fallback skipped for assignments with ternary expressions (#21273)#21293
armorbreak001 wants to merge 1 commit intopython:masterfrom
armorbreak001:fix/ternary-union-fallback

Conversation

@armorbreak001
Copy link
Copy Markdown

Summary

The union_fallback path in infer_rvalue_with_fallback_context() was being incorrectly skipped when the rvalue contained a ternary (ConditionalExpr), because ternary expressions increment the binder version (via frame_context(can_skip=True, fall_through=0) in visit_conditional_expr) just like walrus operators do.

This caused valid type narrowing via reassignment to be lost. For example:

from typing import Iterable

def foo(args: Iterable[str | int] | str | int) -> Iterable[str]:
    if isinstance(args, (str, int)):
        args = (args,)
    args = (
        arg if isinstance(arg, str) else str(arg)
        for arg in args
    )
    return args  # Previously error: got "Generator[str | int, None, None]"

Fix

Replace the binder_version == self.binder.version check with an explicit check for AssignmentExpr (walrus) in the expression tree. This is more precise and does not falsely trigger on ternary expressions or other constructs that happen to increment the binder version.

The helper method _expr_has_assignment_expr() walks the expression tree to check for the presence of any AssignmentExpr node.

Fixes #21273

The union_fallback path in infer_rvalue_with_fallback_context() was
being incorrectly skipped when the rvalue contained a ternary
(ConditionalExpr), because ternary expressions increment the binder
version just like walrus operators do. This caused valid type narrowing
via reassignment to be lost.

Replace the binder_version check with an explicit check for
AssignmentExpr (walrus) in the expression tree, which is more precise
and doesn't falsely trigger on ternary expressions.

Fixes python#21273
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[1.20 regression] mypy no longer detects variable type narrowing via reassignment

1 participant