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

False-positive errors when using type[T] (or Type[T]) in a PEP 604 type alias #12392

Closed
Tracked by #4819
AlexWaygood opened this issue Mar 20, 2022 · 7 comments · Fixed by #14181
Closed
Tracked by #4819

False-positive errors when using type[T] (or Type[T]) in a PEP 604 type alias #12392

AlexWaygood opened this issue Mar 20, 2022 · 7 comments · Fixed by #14181
Labels
affects-typeshed Anything that blocks a typeshed change bug mypy got something wrong false-positive mypy gave an error on correct code topic-pep-604 PEP 604 (union | operator) topic-type-alias TypeAlias and other type alias issues

Comments

@AlexWaygood
Copy link
Member

AlexWaygood commented Mar 20, 2022

Bug Report

The following two snippets (one using builtins.type, the other using typing.Type) both work fine at runtime on 3.10+. They should be accepted as valid type alias definitions on Python 3.10+ (and should be accepted in stub files regardless of Python version). However, mypy raises false-positive errors for both. The errors do not go away if you use typing.TypeAlias:

from typing import Type, TypeAlias

A = type[int] | str  # error: Value of type "Type[type]" is not indexable
B = Type[int] | str  # error: Unsupported left operand type for | ("object")
C: TypeAlias = type[int] | str  # error: Value of type "Type[type]" is not indexable
D: TypeAlias = Type[int] | str  # error: Unsupported left operand type for | ("object")

The order of the types in the union makes no difference when using type[T]: the following two variants still produce errors:

E = str | type[int]  # error: Value of type "Type[type]" is not indexable
F: TypeAlias = str | type[int]  # error: Value of type "Type[type]" is not indexable

However, the order of the types in the union does matter if you're using typing.Type[T]:

B = Type[int] | str  # error: Unsupported left operand type for | ("object")
D: TypeAlias = Type[int] | str  # error: Unsupported left operand type for | ("object")
G = str | Type[int]  # no error

Interestingly, the bug can only be reproduced if type or Type is the outermost object in the type alias. Neither of the following two snippets causes mypy errors:

E = list[type[int] | str]
F = type[int | str]

Mypy is also happy with type[T] or Type[T] being used in old-style typing.Union type aliases:

from typing import Union
G = Union[type[int], str]

To Reproduce

Mypy playground link here.

Expected Behavior

No error should be reported.

Cc. @JelleZijlstra

@AlexWaygood AlexWaygood added the bug mypy got something wrong label Mar 20, 2022
@AlexWaygood AlexWaygood changed the title False-positive errors when using type[T] (or Type[T]`) in a PEP 604 type alias False-positive errors when using type[T] (or Type[T]) in a PEP 604 type alias Mar 20, 2022
@JelleZijlstra JelleZijlstra added the topic-pep-604 PEP 604 (union | operator) label Mar 20, 2022
@AlexWaygood AlexWaygood added the topic-type-alias TypeAlias and other type alias issues label Mar 24, 2022
@AlexWaygood AlexWaygood added the affects-typeshed Anything that blocks a typeshed change label Mar 31, 2022
@wrobell
Copy link

wrobell commented Apr 12, 2022

I have encountered the following

import typing as tp
from collections.abc import Coroutine

T = tp.TypeVar('T')

F: tp.TypeAlias = tp.Callable[[], T] | tp.Callable[[], Coroutine[None, None, T]]  # Unsupported left operand type for | ("object")
G: tp.TypeAlias = tp.Callable[[], T | Coroutine[None, None, T]]  # ok

It looks like the same issue?

@AlexWaygood
Copy link
Member Author

@wrobell, I have another issue open for PEP-604 false-positives with respect to Callable: #12393. But I agree that these problems are linked.

@mthuurne
Copy link
Contributor

This issue seems to exist for any runtime evaluation of type[X], not just in type aliases:

def f() -> type:
    return type[int]  # error: Value of type "Type[type]" is not indexable

This still happens when using the --python-version 3.10 option.

@ilevkivskyi
Copy link
Member

Hm, on current master, two of them work, but other two (with lowercase type) fail with different error

tstalt.py:3: error: Value of type "Type[type]" is not indexable  [index]
tstalt.py:5: error: Value of type "Type[type]" is not indexable  [index]

cc @JukkaL who recently worked on this.

JukkaL added a commit that referenced this issue Nov 24, 2022
Fix aliases like this and other aliases involving new-style unions:
```
A = type[int] | str
```

Fixes #12392. Fixes #14158.
JukkaL added a commit that referenced this issue Nov 25, 2022
Fix aliases like this and other aliases involving new-style unions:
```
A = type[int] | str
```

Fixes #12392. Fixes #14158.
@ppentchev
Copy link

Hi,

Thanks for working on mypy and the related tools!

Is this bug really fixed though? With the attached file (renamed with a .py extension) I get the following:

[roam@straylight ~/tmp/v/roam/woof]$ python3.10 --version
Python 3.10.9
[roam@straylight ~/tmp/v/roam/woof]$ python3.10 -m mypy --version
mypy 0.991 (compiled: yes)
[roam@straylight ~/tmp/v/roam/woof]$ python3.10 -m mypy --python-version=3.10 woof.py
woof.py:12: error: Value of type "Type[type]" is not indexable  [index]
Found 1 error in 1 file (checked 1 source file)
[roam@straylight ~/tmp/v/roam/woof]$ python3.10 woof.py
Handle IPv4Address
[roam@straylight ~/tmp/v/roam/woof]$ python3.10 woof.py some arguments here
Handle IPv6Address
[roam@straylight ~/tmp/v/roam/woof]$

If I use Union to define the IPClass alias, it works just fine. If I put the union - either using Union or the | operator - within the definition of the handle() function, it still works fine:

[roam@straylight ~/tmp/v/roam/woof]$ fgrep -e 'def handle' woof.py
def handle(ipcls: type[ipaddress.IPv4Address] | type[ipaddress.IPv6Address]) -> None:
[roam@straylight ~/tmp/v/roam/woof]$ python3.10 -m mypy --python-version=3.10 woof.py
Success: no issues found in 1 source file
[roam@straylight ~/tmp/v/roam/woof]$

woof.txt

@AlexWaygood
Copy link
Member Author

@ppentchev, there hasn't yet been a mypy release that includes the fix. Are you testing with the mypy master branch?

@ppentchev
Copy link

@AlexWaygood Thanks for the lightning-fast reply! I had actually realized that, and I just came back to leave a "sorry for the noise, I just tested with the Git version and it works just fine!" comment... and you had already replied :)

Thanks again for all your work, and apologies!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
affects-typeshed Anything that blocks a typeshed change bug mypy got something wrong false-positive mypy gave an error on correct code topic-pep-604 PEP 604 (union | operator) topic-type-alias TypeAlias and other type alias issues
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants