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 doesn't work with TypeVar #11780

Closed
MicaelJarniac opened this issue Dec 17, 2021 · 4 comments · Fixed by #11797
Closed

TypeGuard doesn't work with TypeVar #11780

MicaelJarniac opened this issue Dec 17, 2021 · 4 comments · Fixed by #11797
Labels
bug mypy got something wrong

Comments

@MicaelJarniac
Copy link

MicaelJarniac commented Dec 17, 2021

Bug Report

Using a TypeVar with TypeGuard results in Mypy thinking that the resulting type is the TypeVar itself, and not the type it should be pointing to.

To Reproduce

Example adapted from PEP 647:

# src/test.py

from typing import TypeGuard, TypeVar

_T = TypeVar("_T")


def is_two_element_tuple(val: tuple[_T, ...]) -> TypeGuard[tuple[_T, _T]]:
    return len(val) == 2


def func(names: tuple[str, ...]):
    if is_two_element_tuple(names):
        reveal_type(names)  # Tuple[str, str]
        for name in names:
            print(name.capitalize(), "- two")
    else:
        reveal_type(names)  # Tuple[str, ...]
        for name in names:
            print(name.capitalize(), "- not two")

Expected Behavior

Mypy should substitute the TypeVar inside TypeGuard to the proper type it should be pointing to.
Pyre, Pyright, and Pylance do successfully work with the TypeVar inside TypeGuard.

$ pyre
ƛ No type errors found
src/test.py:14:8 Revealed type [-1]: Revealed type for `names` is `typing.Tuple[str, str]`.
src/test.py:18:8 Revealed type [-1]: Revealed type for `names` is `typing.Tuple[str, ...]`.

$ pyright src/test.py
/home/micael/projects/python-3_10/src/test.py
  /home/micael/projects/python-3_10/src/test.py:14:21 - info: Type of "names" is "tuple[str, str]"
  /home/micael/projects/python-3_10/src/test.py:18:21 - info: Type of "names" is "tuple[str, ...]"
0 errors, 0 warnings, 2 infos

Actual Behavior

$ mypy src/test.py
src/test.py:14: note: Revealed type is "Tuple[_T`-1, _T`-1]"
src/test.py:16: error: "_T" has no attribute "capitalize"
src/test.py:18: note: Revealed type is "builtins.tuple[builtins.str]"
src/test.py:19: error: Incompatible types in assignment (expression has type "str", variable has type "_T")
src/test.py:20: error: "_T" has no attribute "capitalize"
Found 3 errors in 1 file (checked 1 source file)

Your Environment

Name Version
Python 3.10.0
typing_extensions 4.0.1
mypy 0.920
mypy-extensions 0.4.3
pyre-check 0.9.8
pyre-extensions 0.0.23
pyright 0.0.13
  • Mypy version used: 0.920
  • Mypy command-line flags: none
  • Mypy configuration options from mypy.ini (and other config files): none
  • Python version used: 3.10.0
  • Operating system and version: Manjaro KDE

Operating System: Manjaro Linux
KDE Plasma Version: 5.23.4
KDE Frameworks Version: 5.88.0
Qt Version: 5.15.2
Kernel Version: 5.15.7-1-MANJARO (64-bit)
Graphics Platform: X11
Processors: 4 × AMD Ryzen 3 2200G with Radeon Vega Graphics
Memory: 7.7 GiB of RAM
Graphics Processor: NVIDIA GeForce GTX 970/PCIe/SSE2

@wbolster
Copy link

i think this can be closed as a duplicate of #11428, @MicaelJarniac? (as you noticed yourself)

@MicaelJarniac
Copy link
Author

I believe the bug in question is to do with TypeVar, and not Generic, as your issue implies.

And in my opinion, the examples I've given here are easier to understand and more straight to the point.

I'm not sure about what to do.

One thing I did not test is whether the issue I'm describing here also happens on Python 3.10, and that's why this issue is about the TypeGuard from typing_extensions.
But the issue you're having seems to be happening on at least Python 3.10.

I do think our issues are about the same bug, but we've come across it in different ways.

I'll try to test my examples against Python 3.10, to see whether it's in any way related to typing_extensions or not.
If it is still happening on 3.10, then I do think we could look into merging both issues onto one.

@MicaelJarniac MicaelJarniac changed the title TypeGuard from typing_extensions doesn't work with TypeVar TypeGuard doesn't work with TypeVar Dec 19, 2021
@MicaelJarniac
Copy link
Author

Just tested it with Python 3.10.0 and using the built-in TypeGuard from typing, and the bug is still there.

@JelleZijlstra
Copy link
Member

Closing as a duplicate of #11428.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug mypy got something wrong
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants