`@overload` incorrectly reports error if overload param would go to different params of implementation depending on positional vs keyword calling style
Personne n'a encore pris cette issue.
- Langage dominant
- Python
- Étoiles
- 20.6k
- Forks
- 3.3k
- Métriques de merge des PR
- Métriques de PR en attente
Description
Bug Report
Type-checking on the @overload decorator incorrectly reports an error in the implementation function's signature when an argument would go to different parameters of an implementation function depending on whether that argument is passed as a positional or keyword argument, even if both outcomes are still valid.
To Reproduce
Here's a minimal possible example:
from typing import overload
@overload
def func(value: int):
...
def func(positional_only: int | None = None, /, value: int | None = None):
pass
func can be correctly called with either of these signatures:
func(1) # results in call with parameters(1, None)
func(value=1) # results in call with parameters (None, 1)
Either of these calls is valid.
Expected Behavior
The type-checker considers the code valid. (Excluding the error that there's only one overload, which is expected in this minimal example).
Actual Behavior
type_test.py:8: error: Overloaded function implementation does not accept all possible arguments of signature 1 [misc]
Your Environment
- Mypy version used: mypy 1.7.1 (compiled: yes)
- Mypy command-line flags:
python3 -m mypy ./type_test_2.py - Mypy configuration options from
mypy.ini(and other config files): Not changed from the default - Python version used: Python 3.11.6
A motivating example
I wanted to define a lookup function that can lookup an object by id (an int) or name (a str), something like this:
from typing import overload
@overload
def lookup(id: int):
...
@overload
def lookup(name: str):
...
def lookup(id_or_name: int | str | None = None, /, id: int | None = None, name: str | None = None):
if id is None and name is None:
if isinstance(id_or_name, int): id = id_or_name
else: name = id_or_name # name is str
if id is not None:
return _lookup_by_id(id)
else:
return _lookup_by_name(name)
## Possible calls:
lookup(1) # integer positional
lookup(id=1) # integer keyword
lookup("foo") # string positional
lookup(name="foo") # string keyword
Guide de contribution
Ouvrir le guide de contribution
Par où commencer
- Lisez l'issue en entier, puis le guide de contribution du projet.
- Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
- Forkez le dépôt et travaillez sur une branche.
- Ouvrez une pull request qui référence le numéro de l'issue.
Piste de recherche
Commencez par exécuter la commande signalée python3 -m mypy ./type_test_2.py avec l’exemple minimal de surcharge et confirmez l’erreur de signature d’implémentation. Suivez la vérification de compatibilité de l’implémentation de surcharge et ajoutez des tests couvrant les appels positionnels et par mot-clé qui atteignent différents paramètres d’implémentation. La tâche est terminée lorsque les appels valides ne produisent plus l’erreur signalée, tandis que les implémentations de surcharge non valides continuent d’être rejetées.
Rédigé par le modèle d'indexation à partir du texte de l'issue.
Évaluation
- Stack technique
- python
- Domaine
- devtools
- Type d'issue
- Bug
- Difficulté
- 4/5
- Temps estimé
- 3-5 jours
- Activité
- À l'abandon
- Clarté
- Clairement spécifiée
- Accessibilité débutants
- 45/100