python / python/mypy

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

Aperta
#16,054 3 commenti 0 reazioni 0 assegnatari Vedi su GitHub

Nessuno ha ancora preso questa issue.

bug
Lingua principale
Python
Stelle
20.6k
Fork
3.3k
Metriche di merge delle PR
Metriche PR in attesa

Descrizione

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)

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

Inizia con il riproduttore nell’issue e segui il modo in cui mypy risolve le chiamate sovraccariche usando l’explode operator. Determina se la chiamata debba essere rifiutata o risolta diversamente, quindi aggiungi una copertura di regressione che dimostri che l’esempio segnalato non supera più erroneamente il controllo dei tipi.

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

Valutazione

Stack tecnologico
python
Ambito
devtools
Tipo di issue
Bug
Difficoltà
5/5
Tempo stimato
Più di una settimana
Stato di attività
Ferma
Chiarezza
Da chiarire
Idoneità per principianti
30/100

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.