Collapsed Optionals in TypeVar cause weird error messages
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
At a minimum, I'm reporting a bug in an error message.
I have a function, run_tasks, which takes a list of tasks and a worker function, and executes the worker function on almost all the tasks. For some of them, run_tasks will decide to not execute the task.
run_tasks returns List[Optional[Result]] where Result is a TypeVar.
This works until the worker function's returns Optional[x] where Result is now Optional[x] and run_tasks is asked to return List[Optional[Optional[x]]].
Example code:
from typing import (
TypeVar,
List,
Callable,
Optional,
)
Task = TypeVar("Task")
Result = TypeVar("Result")
def run_tasks(
tasks: List[Task], worker_fun: Callable[[Task], Result]
) -> List[Optional[Result]]:
results: List[Optional[Result]] = []
toggle: bool = True
todo: Task
for todo in tasks:
toggle = not toggle
if toggle:
work_result: Result
work_result = worker_fun(todo)
results.append(work_result)
else:
results.append(None)
return results
def test() -> None:
def worker(d: int) -> Optional[int]:
if d % 2 == 0:
return None
else:
return d + 1
output: List[Optional[Optional[int]]] = run_tasks(
[1, 2, 2, 1], worker,
)
from pprint import pprint
pprint(output)
assert output == [None, None, None, 2]
test()
I get the error message: error: Argument 2 to "run_tasks" has incompatible type "Callable[[int], Optional[int]]"; expected "Callable[[int], int]"
I understand Python can't really represent Optional[Optional[int]]. The problem is in the error message, I think. This code does work correctly, and validates:
def test2() -> None:
def worker(d: int) -> int:
return d + 1
output: List[Optional[int]] = run_tasks(
[1, 2, 2, 1], worker,
)
from pprint import pprint
pprint(output)
assert output == [None, 3, None, 2]
test2()
and so someone unfamiliar with the intricacies and details may be confused by the type signature being correctly updated in 2 places, but not validating.
Instead, I sort of expected it to either (a) work, or (b) have an error specific to the case of nested Optional.
$ mypy --version
mypy 0.761
$ python --version
Python 3.7.6
flags: none.
My apologies, but I did not test with mypy from Git master.
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 le reproducteur run_tasks fourni avec mypy et comparez le diagnostic de nested-Optional avec le cas test2 qui fonctionne. Le travail est considéré comme terminé lorsque l’erreur de Callable incompatible est corrigée ou remplacée par un diagnostic qui explique correctement ce cas de nested Optional, avec une couverture de régression pour l’exemple.
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