python / python/mypy

explode operator shouldn't be allowed for calls to arrity overloaded functions

Offen
#16,054 3 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

In the test below the intention is that if test is called with one argument that it returns str, and if it is called with multiple that it returns list[str]. The assert will trip at runtime even though the example type checks. The documentation already warns that mypy can't do a perfect job of making sure that your actual implementation function respects the declarations, however, AFAICT there is no correct way to implement test, which makes me think that either this type of overloading should be forbidden or you should be forbidden from using the explode operator when calling such a function (foo, bar, *buzz would be fine but not just *buzz). mypy seems to assume that if you use the explode operator you must mean the overload that takes more than one argument, but in practice because the test implementation can't actually distinguish an explode operator using call from a regular call, the best that it can do is check how many arguments it actually received and assume that you mean the first overload if there is only 1.

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from typing import overload

@overload
def test(x: str) -> str:
    assert False

@overload
def test(x: str, x2: str, *xn: str) -> list[str]:
    assert False

def test(x: str, x2: str | None = None, *xn: str) -> str | list[str]:
    allx = [x]
    if x2 is not None:
        allx.append(x2)
    allx.extend(xn)

    if len(allx) == 1:
        return allx[0]
    return allx

y = ["hi"]
z: list[str] = test(*y)
assert isinstance(z, list)

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 mit dem Reproducer im Issue und verfolge, wie mypy überladene Aufrufe mithilfe des explode operator auflöst. Bestimme, ob der Aufruf abgelehnt oder anders aufgelöst werden sollte, und füge anschließend eine Regressionstestabdeckung hinzu, die zeigt, dass das gemeldete Beispiel nicht mehr fälschlicherweise typgeprüft wird.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Bewertung

Tech-Stack
python
Bereich
devtools
Issue-Typ
Bug
Schwierigkeit
5/5
Geschätzter Aufwand
Über eine Woche
Aktivitätsstatus
Veraltet
Klarheit
Muss geklärt werden
Anfängerfreundlichkeit
30/100

Neue Issues direkt in Ihr Postfach

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