python / python/mypy

TypeGuard does not narrow when assignment expression

Open
#17,088 5 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug topic-pep-572 topic-typeguard-typeis
Dominant language
Python
Stars
20.6k
Forks
3.3k
PR merge metrics
PR metrics pending

Description

Bug Report

In the example below, is_str is a type guard, but when used mypy fails to narrow the type. I'm pretty sure this happens because of the assignment expression.

To Reproduce
https://mypy-play.net/?mypy=latest&python=3.12&gist=42da00a72ace0a51a5d2335721877591

import typing

s: str | int


def is_str(x: str | int) -> typing.TypeGuard[str]:
    return bool(
        isinstance(x, str)
        and (y if len(y := '123'.split('/')) > 1 else '')
    )


if is_str(s):
    s + ''

Expected Behavior
No mypy errors.

Actual Behavior

main.py:14: error: Unsupported operand types for + ("int" and "str") [operator]
main.py:14: note: Left operand is of type "str | int"
Found 1 error in 1 file (checked 1 source file)

Your Environment

  • Mypy version used: 1.19
  • Mypy command-line flags: non
  • Mypy configuration options from mypy.ini (and other config files): non
  • Python version used: 3.12

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 with the mypy-play reproducer and inspect how the TypeGuard call is analyzed when the guard contains an assignment expression. Use main.py's reported line as the expected narrowing check; done means the unsupported operand error is gone and the existing reproduction passes.

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
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.