Binding of Generic decorators on Union variables
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 seems to bind the TypeVar of a Generic decorator incorrectly when a variable is annotated as a Union.
To Reproduce
This example is based on this untyped cython code.
from typing import Callable, Generic, Optional, TypeVar, Union, overload
F = TypeVar("F")
G = TypeVar("G")
class cache_readonly(Generic[F, G]):
def __init__(self, func: Callable[[F], G]) -> None:
self.func = func
self.name = func.__name__
self.__doc__ = getattr(func, "__doc__", None)
@overload
def __get__(self, obj: F, typ) -> G:
...
@overload
def __get__(self, obj: None, typ) -> "cache_readonly[F, G]":
...
def __get__(self, obj: Optional[F], typ) -> Union[G, "cache_readonly[F, G]"]:
if obj is None:
# accessed on the class, not the instance
return self
# Get the cache or set a default one if needed
cache = getattr(obj, "_cache", None)
if cache is None:
cache = obj._cache = {} # type: ignore
if self.name in cache:
val = cache[self.name]
else:
val = self.func(obj)
cache[self.name] = val
return val
def __set__(self, obj: F, value: G) -> None:
raise AttributeError("Can't set attribute")
class TestA:
@cache_readonly
def x(self) -> str:
return "A"
class TestB:
@cache_readonly
def x(self) -> str:
return "B"
def test(obj: Union[TestA, TestB]) -> str:
return obj.x
Expected Behavior
Mypy and pyright are happy with the code :)
Actual Behavior
mypy
test.py:55: error: Argument 1 to "__get__" of "cache_readonly" has incompatible type "Union[TestA, TestB]"; expected "TestA"
test.py:55: error: Argument 1 to "__get__" of "cache_readonly" has incompatible type "Union[TestA, TestB]"; expected "TestB"
Pyright doesn't complain (except for the __doc__ line).
Your Environment
- Mypy version used: 0.910
- Mypy command-line flags: -
- Mypy configuration options from
mypy.ini(and other config files): - - Python version used: 3.9.6
- Operating system and version: CentOS 3.10.0-693.5.2.el7.x86_64
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
Reproduisez le rapport avec l’exemple test.py en utilisant mypy 0.910 et comparez ses diagnostics avec le comportement attendu et le résultat de pyright. C’est terminé lorsque l’accès à Union[TestA, TestB] ne produit plus d’erreurs d’arguments incompatibles de get, tout en préservant le comportement montré du décorateur.
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é
- Plutôt claire
- Accessibilité débutants
- 35/100