at runtime dataclass special-cases FunctionType, but at type-time mypy special-cases Callable, leading to mismatches
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
If you declare an attribute on a dataclass to be Callable, Mypy assumes that its __get__ will not be called, even on a default attribute. But this is only true if the default is a FunctionType, not some other type of callable.
Similarly, the inverse is true: an abstract type (such as a callable Protocol) will tell mypy that __get__ will be called, even though if the concrete default value is a FunctionType, it won't be.
Specifically, the following program contains 2 type errors, but MyPy does not think so:
To Reproduce
from __future__ import annotations
from typing import Callable, Protocol, ParamSpec, TypeVar, Generic
from dataclasses import dataclass
def f() -> None:
print("hello world")
def f2(self: object) -> None:
print("bound self", self)
P = ParamSpec("P")
T = TypeVar("T")
R = TypeVar("R", covariant=True)
T_con = TypeVar("T_con", contravariant=True)
class BindableMethod(Protocol[T_con, R]):
def __get__(self, instance: T_con, owner: None | type[object]) -> Callable[[], R]:
...
def __call__(me, self: T_con) -> R:
...
class UnboundNonFunction(Generic[P, R]):
def __call__(self) -> int:
print("unbound")
return 3
def __get__(self, instance: object, owner: type | None) -> BoundNonFunction:
print("binding", instance, owner)
return BoundNonFunction(instance)
@dataclass(frozen=True)
class BoundNonFunction:
instance: object
def __call__(self) -> str:
print("bound", self.instance)
return "wat"
@dataclass
class FuncHolder():
func: Callable[[], None] = f
func2: BindableMethod[FuncHolder, None] = f2
func3: Callable[[], int] = UnboundNonFunction()
FuncHolder().func()
try:
FuncHolder().func2()
except Exception as e:
print("whoops", str(e))
try:
print(FuncHolder().func3() + 4)
except Exception as e:
print("whoops 2", str(e))
https://mypy-play.net/?mypy=latest&python=3.11&gist=1ac4e7c090774489207dfbc737de2d61
Expected Behavior
I would expect runtime and type-time behavior to be consistent here. Specifically I just don't expect __get__ to be called on things with a Callable type.
Actual Behavior
Mypy succeeds, rather than reporting the type errors.
Your Environment
- Mypy version used: mypy 1.1.1 (compiled: yes)
- Mypy command-line flags: none
- Mypy configuration options from
mypy.ini(and other config files): none - Python version used: 3.11.2 (python.org, macOS, aarch64)
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 la reproduction Python autonome fournie dans l’issue et exécutez-la avec mypy-play en utilisant la configuration liée. Comparez le comportement du descripteur dataclass à l’exécution avec le traitement par mypy des valeurs par défaut typées comme Callable et comme des protocoles. C’est terminé lorsque mypy signale les deux erreurs de typage tout en conservant le cas valide de FunctionType.
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
- 25/100