python / python/typeshed

`ElementTree.parse` type hinted to return unusable generic types

Offen
#14,672 3 Kommentare 1 Reaktion 0 zugewiesene Personen Auf GitHub ansehen

Dieses Issue hat noch niemand übernommen.

Vorherrschende Sprache
Python
Sterne
5.1k
Forks
2.1k
Ø Merge
1 T. 19 Std.
Gemergte PRs (30 T.)
82

Beschreibung

Bug Report

Since upgrading to mypy 1.15+, using ElementTree has become increasingly difficult. Likely due to https://github.com/python/typeshed/pull/13349. I'm not sure if this extra strictness is expected or if I'm just holding it wrong.

One example is the ElementTree.parse function that now returns a generic ET.ElementTree[ET.Element[str]], which is no longer compatible with basic type signatures like ET.ElementTree, which is interpreted as ElementTree[Element[str] | None].

This adds many challenges that make it difficult to work with.

  • The generic argument here is very difficult to understand what it means and is lacking documentation. From what i've been able to deduce it's possible that the root node is of a different Element type or that the root node is None. While perhaps a valid scenario, it adds a big uphill to learning and usability.
  • If one were to use these generic types, typing out ET.ElementTree[ET.Element[str]] is a lot more verbose than ET.ElementTree, and i'm questioning if the strictness here is worth it.
  • If one tries to type hint the code with these generics. Python throws errors that 'ElementTree.Element' is not subscriptable. One workaround i found for this is to surround the type hints with double-quotes.

To Reproduce

import xml.etree.ElementTree as ET

def process_document(doc: ET.ElementTree) -> None:
    pass

def process_document2(doc: ET.ElementTree[ET.Element[str]]) -> None:    # TypeError: type 'xml.etree.ElementTree.Element' is not subscriptable
    pass

process_document(ET.parse("foo.xml"))     # mypy error: Argument 1 to "process_document" has incompatible type "ElementTree[Element[str]]"; expected "ElementTree[Element[str] | None]"  [arg-type]
process_document2(ET.parse("foo.xml"))

Run with mypy --strict

Expected Behavior

ET.parse returns types assignable to ET.ElementTree

Actual Behavior

Mypy returns errror

# mypy error: Argument 1 to "process_document" has incompatible type "ElementTree[Element[str]]"; expected "ElementTree[Element[str] | None]"  [arg-type]

Workarounds

  • Use ET.ElementTree().parse() function instead of ET.parse(), it returns the root-node as a type that can be assigned to ET.Element without any generic arguments.
    This is actually a pretty decent option, if this is considered to be the primary way of using ElementTree from now on, the documentation should reflect that, right now it's suggesting ET.parse()
  • Type out the complete "ElementTree[Element[str] | None]" wrapped with double-quotes.

Your Environment

  • Mypy version used:
  • Mypy command-line flags:
  • Mypy configuration options from mypy.ini (and other config files):
  • Python version used:

Beitragsleitfaden

Beitragsleitfaden öffnen

Erste Schritte

  1. Lies das ganze Issue und danach den Beitragsleitfaden des Projekts.
  2. Schreib ins Issue, dass du es übernimmst — das erspart doppelte Arbeit.
  3. Forke das Repository und arbeite in einem Branch.
  4. Öffne einen Pull Request, der die Issue-Nummer nennt.

Rechercherichtung

Beginne mit dem Lesen von typeshed PR 13349 und der Annotationen für ElementTree.parse, und vergleiche sie anschließend mit dem ElementTree().parse()-Workaround und der Python ElementTree-Dokumentation. Als abgeschlossen gilt die Aufgabe, wenn das beabsichtigte generische Verhalten und die erwartete Zuweisbarkeit von ET.parse() geklärt sind und das entsprechende Typing- oder Dokumentationsproblem behoben ist.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Bewertung

Tech-Stack
python
Bereich
devtools
Issue-Typ
Bug
Schwierigkeit
4/5
Geschätzter Aufwand
3-5 Tage
Aktivitätsstatus
Veraltet
Klarheit
Größtenteils klar
Anfängerfreundlichkeit
35/100

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.