Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TypeGuard does not narrow when statement compares for identity (is True) #17483

Open
flaeppe opened this issue Jul 4, 2024 · 3 comments
Open
Assignees
Labels
bug mypy got something wrong topic-type-narrowing Conditional type narrowing / binder topic-typeguard TypeGuard / PEP 647

Comments

@flaeppe
Copy link

flaeppe commented Jul 4, 2024

Bug Report

In the example below f is a TypeGuard that mypy fails to narrow the type with when the statement compares with identity (is True)

To Reproduce

https://mypy-play.net/?mypy=master&python=3.12&flags=strict&gist=688d7597c968ed90ecdd8d4bf2b3a8a3

from typing import TypeGuard

def f(value: str) -> TypeGuard[int]:
    return True

# This should narrow to "builtins.int"
by_identity = "123"
assert f(by_identity) is True
reveal_type(by_identity)  # Revealed type is "builtins.str"

Expected Behavior

Revealed type is "builtins.int"

Actual Behavior

Revealed type is "builtins.str"

Your Environment

  • Mypy version used: 1.10.1 (and master)
  • Mypy command-line flags:
  • Mypy configuration options from mypy.ini (and other config files):
  • Python version used: 3.12
@flaeppe flaeppe added the bug mypy got something wrong label Jul 4, 2024
@sobolevn
Copy link
Member

sobolevn commented Jul 6, 2024

The same happens for

by_identity = "123"
assert f(by_identity) == True
reveal_type(by_identity)  # Revealed type is "builtins.str"

@sobolevn
Copy link
Member

sobolevn commented Jul 6, 2024

This happens because we only check for type guards here:

mypy/mypy/checker.py

Lines 5837 to 5839 in ec00fb8

elif isinstance(node.callee, RefExpr):
if node.callee.type_guard is not None or node.callee.type_is is not None:
# TODO: Follow *args, **kwargs

But, is True / == True is checked in this branch:

elif isinstance(node, ComparisonExpr):

It never really calls the first branch for its operands.

I think it would make sense to move the type guard part into a helper function and call it from both branches.

@flaeppe I can assign this on you if you want :)

@flaeppe
Copy link
Author

flaeppe commented Jul 6, 2024

@flaeppe I can assign this on you if you want :)

Sure, go ahead.

And thank you for the insight, I'll try to have a look

@sobolevn sobolevn added topic-type-narrowing Conditional type narrowing / binder topic-typeguard TypeGuard / PEP 647 labels Jul 6, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug mypy got something wrong topic-type-narrowing Conditional type narrowing / binder topic-typeguard TypeGuard / PEP 647
Projects
None yet
Development

No branches or pull requests

2 participants