python / python/mypy

Unions of homogeneous collections unnecessarily broadened when used to construct a new collection

Offen
#18,869 0 Kommentare 0 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen

Dieses Issue hat noch niemand übernommen.

bug
Vorherrschende Sprache
Python
Sterne
20.6k
Forks
3.3k
PR-Merge-Kennzahlen
PR-Kennzahlen ausstehend

Beschreibung

Bug Report

mypy infers an incorrectly broad type in some cases where collections are constructed from a collection whose type is a union. In particular, if the input to a collection constructor is a union of collections with homogeneous element types, the type that mypy infers ignores the fact that the inputs are homogeneous. The type mypy infers is not wrong (in that the actual type will be covered by it), but it is unnecessarily broad (it matches types which are obviously not possible -- i.e., a collection with heterogeneous element types).

To Reproduce

https://mypy-play.net/?mypy=latest&python=3.12&gist=04f25887cd105eefebfdcbdbd3c03665
https://gist.github.com/mypy-play/04f25887cd105eefebfdcbdbd3c03665

from typing import Generator
from typing_extensions import reveal_type

list_union: list[int] | list[None]
set_union: set[int] | set[None]
tuple_union: tuple[int, ...] | tuple[None, ...]
generator_union: Generator[int, None, None] | Generator[None, None, None]

# Expected: "Union[builtins.list[builtins.int], builtins.list[None]]"
# Actual: "builtins.list[Union[builtins.int, None]]"
reveal_type(list(list_union))
reveal_type(list(set_union))
reveal_type(list(tuple_union))
reveal_type([x for x in generator_union])

# Expected: "Union[builtins.set[builtins.int], builtins.set[None]]"
# Actual: "builtins.set[Union[builtins.int, None]]"
reveal_type(set(list_union))
reveal_type(set(set_union))
reveal_type(set(tuple_union))
reveal_type({x for x in generator_union})

# Expected: "Union[builtins.tuple[builtins.int, ...], builtins.tuple[None, ...]]"
# Actual: "builtins.tuple[Union[builtins.int, None], ...]"
reveal_type(tuple(list_union))
reveal_type(tuple(set_union))
reveal_type(tuple(tuple_union))
reveal_type(tuple(x for x in generator_union))

Expected Behavior

Because mypy knows that the argument to the collection constructor is a collection whose elements are all of the same type, I assumed it would thus realize that it would result in a collection whose elements are all of the same type.

Actual Behavior

mypy incorrectly reports that the resulting collection may have heterogeneous element types.

Your Environment

  • Mypy version used: 1.15.0
  • Mypy command-line flags: None
  • Mypy configuration options from mypy.ini (and other config files): None
  • Python version used: 3.12

Beitragsleitfaden

Beitragsleitfaden öffnen

Erste Schritte

  1. Lies das ganze Issue und danach den Beitragsleitfaden des Projekts.
  2. Schreib ins Issue, dass du es übernimmst — das erspart doppelte Arbeit.
  3. Forke das Repository und arbeite in einem Branch.
  4. Öffne einen Pull Request, der die Issue-Nummer nennt.

Rechercherichtung

Beginne damit, den Python-Reproducer aus dem Issue oder dem verlinkten mypy-play-Gist auszuführen, und vergleiche die Ergebnisse von reveal_type mit den erwarteten Unions. Verfolge mypys Verarbeitung von Collection-Konstruktoren und Comprehensions für Unions homogener Collections. Als erledigt gilt die Aufgabe, wenn die Beispiele die entsprechende Union homogener List-, Set- und Tuple-Typen inferieren, ohne heterogene Elementtypen einzuführen.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Bewertung

Tech-Stack
python
Bereich
devtools
Issue-Typ
Bug
Schwierigkeit
4/5
Geschätzter Aufwand
3-5 Tage
Aktivitätsstatus
Veraltet
Klarheit
Größtenteils klar
Anfängerfreundlichkeit
45/100

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.