python / python/mypy

Unexpected Overloading overlap if String Literal is used within Sequence/Iterable/Collection

Ouverte
#15,035 6 commentaires 1 réaction 0 personnes assignées Voir sur GitHub

Personne n'a encore pris cette issue.

bug topic-overloads
Langage dominant
Python
Étoiles
20.6k
Forks
3.3k
Métriques de merge des PR
Métriques de PR en attente

Description

Bug Report

If I have a function that accepts a String Literal and Sequence of String Literal and want to overload this function for these two cases, mypy always returns:

Overloaded function signatures 1 and 2 overlap with incompatible return types [misc]

from typing import overload, Literal

@overload
def over(bar: Literal["bar"]) -> int:  # Overloaded function signatures 1 and 2 overlap with incompatible return types  [misc]
    ...

@overload
def over(bar: Sequence[Literal["foo"]]) -> str:
    ...   

def over(bar: Literal["bar"]|Sequence[Literal["foo"]]) -> str|int:
    if bar == "bar":
        return 0
    return ", ".join(bar)
    

To Reproduce
https://mypy-play.net/?mypy=latest&python=3.11&gist=d28d528c0765dc0a4a004c360a4008a4

Expected Behavior

No error, as if we would use a list instead:

@overload
def load(bar: Literal["bar"]) -> int:
    ...

@overload
def load(bar: list[Literal["foo"]]) -> str:
    ...   

def load(bar: Literal["bar"]|list[Literal["foo"]]) -> str|int:
    if bar == "bar":
        return 0
    return ", ".join(bar)

Actual Behavior
Mypy returns:

Overloaded function signatures 1 and 2 overlap with incompatible return types [misc]

Your Environment

MyPy playground....

  • Mypy version used: 1.20
  • Mypy command-line flags: none
  • Mypy configuration options from mypy.ini (and other config files): none
  • Python version used: tested with 3.10 and 3.11

Note
I am aware that a str is also a Sequence[str]. But as we using literals here, this shouldn't matter.

This is only an issue for mypy if used with overloads, it works correctly if simply used within a function

# Simple example, that if we use Sequences and Literals, mypy
# can determine stuff correctly
def foo(bar: Literal["bar"]|Sequence[Literal["foo"]]) -> None:
    return None
    
    
foo("bar")  # okay
foo(["foo"]) # okay
foo("foo") # not okay - as expected
foo(["bar"]) # not okay - as expected

Note that pyright does detect the overloads correctly (kind of).

Guide de contribution

Ouvrir le guide de contribution

Par où commencer

  1. Lisez l'issue en entier, puis le guide de contribution du projet.
  2. Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
  3. Forkez le dépôt et travaillez sur une branche.
  4. Ouvrez une pull request qui référence le numéro de l'issue.

Piste de recherche

Commencez par exécuter la reproduction mypy-play liée et comparez les exemples de surcharge utilisant Sequence, Iterable, Collection et list avec les vérifications finales des appels de fonction. Suivez la compatibilité des surcharges et la gestion de Literal impliquées dans le diagnostic signalé. Le travail est terminé lorsque les surcharges valides de String Literal et de séquence ne produisent plus d’erreur de chevauchement incompatible, tandis que les appels invalides restent rejetés.

Rédigé par le modèle d'indexation à partir du texte de l'issue.

Évaluation

Stack technique
python
Domaine
compilers, devtools
Type d'issue
Bug
Difficulté
4/5
Temps estimé
3-5 jours
Activité
À l'abandon
Clarté
Plutôt claire
Accessibilité débutants
35/100

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.