Union of `Never` can't be used
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
Functions which optionally take a value of Never type have impossible requirements placed on usages of that optional value.
To Reproduce
https://gist.github.com/mypy-play/a49d72bdacc179ffda5f69d8b66f41ff
from typing import Never
def blah(s: Never | str) -> None:
print(s + "hi")
Expected Behavior
The code type-checks. Since it is impossible for any variable to take a value of type Never, the type signature of blah is equivalent to str -> None. The function's body is valid when s is annotated with type str, so it should be valid when annotated with Never | str.
Actual Behavior
main.py:5: error: Unsupported left operand type for + ("Never") [operator]
main.py:5: note: Left operand is of type "Never | str"
Found 1 error in 1 file (checked 1 source file)
Your Environment
- Python 3.12
- MyPy 1.15.0, invocation as performed in the Playground
Background
Pyright appears to do the right thing here: it accepts this code.
I ran into this when implementing this pattern, which is me placing types around something I found untyped in the wild:
T = TypeVar("T", contravariant=True)
class _MyProtocol(Protocol[T]):
def _foo(self, arg: T | IO[str]) -> None: ...
try:
import foo
class _MyImpl(_MyProtocol[foo.Foo]):
def _foo(self, arg: foo.Foo | IO[str]) -> None:
# do something here
pass
MyType = _MyImpl
except ImportError:
class _MyImplNone(_MyProtocol[Never]):
def _foo(self, arg: Never | IO[str]) -> None:
# correctly assume arg is an IO[str] here
pass
MyType = _MyImplNone
That way, MyType has type _MyProtocol[foo.Foo] | _MyProtocol[Never], allowing a type-level discrimination of whether the foo functionality is present or not.
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 le reproducteur minimal en Python présent dans l’issue ou dans l’exemple mypy-play lié, puis comparez l’erreur d’opérateur signalée au comportement attendu équivalent à str. Suivez la manière dont les unions contenant Never sont traitées lors de la vérification des types, puis ajoutez une couverture pour la fonction présentée et confirmez que mypy l’accepte sans l’erreur d’opérande Never.
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
- 42/100