`@overload` breaks with named tuple and some overloaded functions
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
Mypy incorrectly reports Any as the resolved type (quite possibly due this https://github.com/python/typing/issues/253#issuecomment-235358878 )
To Reproduce
from collections import namedtuple
from typing import Any, Callable, cast, Dict, List, NamedTuple, overload, TypeVar, Union
F = TypeVar("F", bound=Callable[..., Any])
Arg: NamedTuple = namedtuple("Arg", ["arg"])
class Test:
@overload
def __call__(self, fn: F) -> F:
...
@overload
def __call__(self, *args: Any, **kwargs: Any) -> "Test":
...
def __call__(self, *args: Any, **kwargs: Any) -> Union[F, "Test"]:
if len(args) == 1:
return cast(F, args[0])
return self
reveal_type(Test()(Test))
def broken(arg: Arg) -> Arg:
return arg
reveal_type(broken)
reveal_type(Test()(broken))
def working(arg: int) -> int:
return arg
reveal_type(Test()(working))
@overload
def overloaded_broken(arg: F) -> F:
...
@overload
def overloaded_broken(*args: Any, **kwargs: Any) -> Dict[str, int]:
...
def overloaded_broken(*args: Any, **kwargs: Any) -> Union[F, Dict[str, int]]:
if len(args) == 1:
return cast(F, args[0])
return dict(args=len(args), kwargs=len(kwargs))
reveal_type(overloaded_broken)
reveal_type(Test()(overloaded_broken))
@overload
def overloaded_working(arg: str) -> str:
...
@overload
def overloaded_working(arg: bytes) -> bytes:
...
def overloaded_working(arg: Union[bytes, str]) -> Union[bytes, str]:
return arg
reveal_type(Test()(overloaded_working))
Expected Behavior
All revealed types are printed as non Any
Actual Behavior
# a class is OK
test.py:23:13: note: Revealed type is 'def () -> test.Test'
# this is what is expected when using a named tuple, but it resolves as any
test.py:30:13: note: Revealed type is 'def (arg: Tuple[Any, fallback=test.Arg]) -> Tuple[Any, fallback=test.Arg]'
test.py:31:13: note: Revealed type is 'Any'
# this is not using a named tuple and it works as expected
test.py:38:13: note: Revealed type is 'def (arg: builtins.int) -> builtins.int'
# this is what is expected for a complex overloaded function, but it resolves as any
test.py:57:13: note: Revealed type is 'Overload(def [F <: def (*Any, **Any) -> Any] (arg: F`-1) -> F`-1, def (*args: Any, **kwargs: Any) -> builtins.dict[builtins.str, builtins.int])'
test.py:58:13: note: Revealed type is 'Any'
# passing a simpler overloaded function
test.py:73:13: note: Revealed type is 'Overload(def (arg: builtins.str) -> builtins.str, def (arg: builtins.bytes) -> builtins.bytes)'
Your Environment
mypy --version: mypy 0.812 (default config)
python --version: Python 3.8.9
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 reproduction dans test.py avec mypy 0.812 et comparez les revealed types pour les cas named-tuple et overloaded-function. Suivez la résolution de surcharge et le traitement des types named-tuple, puis vérifiez que les reveals concernés se résolvent en leurs types callable attendus plutôt qu'en Any.
Rédigé par le modèle d'indexation à partir du texte de l'issue.
Évaluation
- Stack technique
- python
- Domaine
- compilers
- Type d'issue
- Bug
- Difficulté
- 4/5
- Temps estimé
- 3-5 jours
- Activité
- À l'abandon
- Clarté
- Plutôt claire
- Accessibilité débutants
- 35/100