python / python/mypy

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

Aperta
#13,960 1 commento 0 reazioni 0 assegnatari Vedi su GitHub

Nessuno ha ancora preso questa issue.

bug topic-join-v-union
Lingua principale
Python
Stelle
20.6k
Fork
3.3k
Metriche di merge delle PR
Metriche PR in attesa

Descrizione

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

Guida per i contributori

Apri la guida per i contributori

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Direzione di ricerca

Riproduci gli esempi con mypy --strict, incluse le chiamate a set/list e la funzione generica personalizzata che usa Iterable e TypeVar. Traccia i punti di ingresso dell’inferenza generica e della gestione delle unioni; il lavoro è completato quando reveal_type preserva l’unione di collezioni di int e str invece di ampliare l’argomento di tipo a object.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Valutazione

Stack tecnologico
python
Ambito
devtools
Tipo di issue
Bug
Difficoltà
4/5
Tempo stimato
3-5 giorni
Stato di attività
Ferma
Chiarezza
Abbastanza chiara
Idoneità per principianti
35/100

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.