Type narrowing for Optional[T] fails inside an else branch inside a while cycle
Dieses Issue hat noch niemand übernommen.
- Vorherrschende Sprache
- Python
- Sterne
- 20.6k
- Forks
- 3.3k
- PR-Merge-Kennzahlen
- PR-Kennzahlen ausstehend
Beschreibung
Bug Report
from typing import Optional
class Node:
def __init__(self, value: int):
self.value = value
self.next: Optional[Node] = None
def foo(node: Node) -> None:
while node.next is not None:
if node.value != node.next.value:
node = node.next
else:
node.next = node.next.next # <-- HERE
Expected Behavior
No mypy errors. Mypy should know that node.next is not None in the else branch.
Actual Behavior
Mypy says error: Item "None" of "Optional[Node]" has no attribute "next" on the line marked by <-- HERE. (With column numbers turned on, the location is the beginning of node.next.next.)
Interestingly, everything is OK if the branches of if are reversed:
def foo(node: Node) -> None:
while node.next is not None:
if node.value == node.next.value:
node.next = node.next.next
else:
node = node.next
Writing assert node is not None before the problematic line also fixes the error (but seems quite redundant).
Your Environment
- Mypy version used: mypy 0.930
- Mypy command-line flags: none
- Mypy configuration options from
mypy.ini(and other config files): default, no config files - Python version used: Python 3.10.1
- Operating system and version: Arch Linux
Beitragsleitfaden
Erste Schritte
- Lies das ganze Issue und danach den Beitragsleitfaden des Projekts.
- Schreib ins Issue, dass du es übernimmst — das erspart doppelte Arbeit.
- Forke das Repository und arbeite in einem Branch.
- Öffne einen Pull Request, der die Issue-Nummer nennt.
Rechercherichtung
Beginne damit, mypy 0.930 ohne Konfiguration für das im Issue enthaltene Optional[Node]-Beispiel auszuführen; vergleiche dann die beiden Verzweigungsreihenfolgen und die assert-Variante. Verfolge die Typverengung rund um die while-Bedingung und die Zuweisung; abgeschlossen ist die Aufgabe, wenn das ursprüngliche Beispiel ohne das redundante assert keinen Fehler meldet.
Vom Indexierungsmodell aus dem Issue-Text verfasst.
Bewertung
- Tech-Stack
- python
- Bereich
- compilers
- Issue-Typ
- Bug
- Schwierigkeit
- 3/5
- Geschätzter Aufwand
- 1-2 Tage
- Aktivitätsstatus
- Veraltet
- Klarheit
- Größtenteils klar
- Anfängerfreundlichkeit
- 42/100