Allow returning `AnyOf` rather than `Any` for amiguous overloads.
Personne n'a encore pris cette issue.
- Langage dominant
- Python
- Étoiles
- 1.8k
- Forks
- 302
- Merge moyen
- 23 h
- PR mergées (30 j)
- 8
Description
Currently, the typing spec for overloads, step 5, states that
Once this filtering process is applied for all arguments, examine the return types of the remaining overloads. If these return types include type variables, they should be replaced with their solved types. If the resulting return types for all remaining overloads are equivalent, proceed to step 6.
If the return types are not equivalent, overload matching is ambiguous. In this case, assume a return type of Any and stop.
However, couldn't this rule be relaxed to returning the union of the return type of all matching overloads? For instance, consider this example derived from a real world use case (numpy scalar ops)
from typing import Any, overload, assert_type
class A[T]: # covariant
def get(self) -> T: ...
@overload
def op(l: A[None], r: A[None]) -> A[None]: ...
@overload
def op(l: A[None], r: A[Any]) -> A[None]: ...
@overload
def op(l: A[Any], r: A[None]) -> A[None]: ...
@overload
def op(l: A[Any], r: A[Any]) -> A[Any]: ...
def test(x: A[None], y: A[Any]) -> None:
assert_type(op(x, x), A[None]) # spec: ✅️
assert_type(op(x, y), A[None]) # spec: ✅️
assert_type(op(y, x), A[None]) # spec: ✅️
assert_type(op(y, y), A[Any] | A[None]) # spec: ❌️ (expected Any)
According to the rule stated above, op(A[Any], A[Any]) should be inferred to as Any, because the overloads are ambious and A[Any] is not equivalent to A[None] as not all materializations of A[Any] can be assigned to A[None].
However inferring Any loses deducible information: we know that no matter what, the return type must be an A. So in principle the return type should be A[Any] | A[None], because if either the left argument or the right argument materializes to A[None], then we get A[None] and otherwise if they materialize to something else we get A[Any].
Guide de contribution
Aucun guide de contribution indexé pour ce dépôt
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 l’étape 5 de la spécification des overloads et par la définition de glossary de equivalent liée dans l’issue. Analysez l’exemple A[Any] et A[None] et déterminez si les overloads ambigus doivent conserver une union plutôt que devenir Any. C’est terminé lorsque la spécification de typing comporte une règle décidée et documentée pour ce cas et que l’exemple reflète cette règle.
Rédigé par le modèle d'indexation à partir du texte de l'issue.
Évaluation
- Stack technique
- python
- Domaine
- documentation
- Type d'issue
- Fonctionnalité
- Difficulté
- 5/5
- Temps estimé
- Plus d'une semaine
- Activité
- À l'abandon
- Clarté
- Plutôt claire
- Accessibilité débutants
- 30/100