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

Type argument lost when union of collections is passed to generic function #13960

Open
daniil-berg opened this issue Oct 28, 2022 · 1 comment
Labels
bug mypy got something wrong topic-join-v-union Using join vs. using unions

Comments

@daniil-berg
Copy link

daniil-berg commented Oct 28, 2022

Bug Report

Passing a union of collections to a generic function that should preserve the type argument erases it instead. (Or should I say it consolidates it to object?)

To Reproduce

from typing import Union

x: list[int] | list[str]
y: Union[set[int], set[str]]

reveal_type(set(x))
reveal_type(list(y))

Expected Behavior

Revealed type is "Union[builtins.set[builtins.int], builtins.set[builtins.str]]"
Revealed type is "Union[builtins.list[builtins.int], builtins.list[builtins.str]]"

I hope this is reasonable. I mean, the type argument is either one or the other and nothing else.

Actual Behavior

Revealed type is "builtins.set[builtins.object]"
Revealed type is "builtins.list[builtins.object]"

Environment

Python 3.10.8 on Linux; mypy --strict version 0.982

More examples

Clearly mypy is capable of preserving the type argument, when there is no union of iterables passed to set:

reveal_type(set([1, 2]))  # Revealed type is "builtins.set[builtins.int]"

It also does not seem to have anything to do with the wrong typeshed stubs, as the same problem occurs with custom generic functions:

from collections.abc import Iterable
from typing import TypeVar

T = TypeVar("T")

def f(i: Iterable[T]) -> T:
    ...

z: list[int] | list[str]

reveal_type(f(z))  # Revealed type is "builtins.object"

The following gives me an error:

def my_set(a: list[int] | list[str]) -> set[int] | set[str]:
    return set(a)  # Incompatible return value type (got "Set[object]", expected "Union[Set[int], Set[str]]")

And yes, I know this would be better solved with a generic type variable instead of the unions. It is just to provide an additional demonstration of what I consider a bug.


My description of the problem may be poorly worded. Please feel free to correct me, so that I can describe it more precisely.

This issue seems vaguely related: #6463

@daniil-berg daniil-berg added the bug mypy got something wrong label Oct 28, 2022
@erictraut
Copy link

This is another issue caused by mypy using joins instead of unions. The join of int and str results in object.

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-join-v-union Using join vs. using unions
Projects
None yet
Development

No branches or pull requests

3 participants