attrs plugin does not support generic type
Dieses Issue hat noch niemand übernommen.
- Vorherrschende Sprache
- Python
- Sterne
- 20.6k
- Forks
- 3.3k
- PR-Merge-Kennzahlen
- PR-Kennzahlen ausstehend
Beschreibung
Bug Report
The mypy attrs plugin has custom support for attrs.evolve, which has different code branches for regular and generic types (starting here).
It admits attrs.has as a type guard for attrs.evolve if the original type is Any, but not if it's a generic type parameter T with no type bound.
To Reproduce
On python 3.12 (so lacking copy.replace):
def replace[T](value: T, **kwargs: Any) -> T:
if attrs.has(type(value)):
return attrs.evolve(value, **kwargs)
else:
raise NotImplementedError(f"replace is not implemented for {type(value)}")
Mypy reports, error: Argument 1 to "evolve" has a variable type "T" not bound to an attrs class [misc]
(In the actual code I'd do something else in other branches; this is intended as a replacement for copy.replace on python < 3.13, supporting different types besides attrs classes.)
Using the attr.AttrInstance protocol also doesn't work, which means I can't define my own type guard wrapping attrs.has. This code results in the same mypy error:
def replace[T: attrs.AttrsInstance](value: T, **kwargs: Any) -> T:
return attrs.evolve(value, **kwargs)
However, this code works (and is a viable workaround):
def replace[T](value: T, **kwargs: Any) -> T:
val2: Any = value
if attrs.has(type(val2)):
return attrs.evolve(val2, **kwargs)
else:
raise NotImplementedError(f"replace is not implemented for {type(value)}")
Expected Behavior
Mypy should honor attrs.has as a type guard for attrs.evolve, whether the original type is generic or any other kind.
- Mypy version used: 1.15.0
- Python version used: 3.12.10
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 in mypy/plugins/attrs.py bei der Behandlung von attrs.evolve in der Nähe von Zeile 914 und führe dann das bereitgestellte generische Python-3.12-Beispiel mit mypy 1.15.0 aus, um die Diagnose zu beobachten. Verfolge, wie attrs.has für Any im Vergleich zu einem nicht gebundenen Typparameter erkannt wird, und bestätige den Abschluss, wenn das generische Beispiel ohne den Variablentypfehler akzeptiert wird und dabei der erwartete Rückgabetyp erhalten bleibt.
Vom Indexierungsmodell aus dem Issue-Text verfasst.
Bewertung
- Tech-Stack
- python
- Bereich
- tooling
- Issue-Typ
- Bug
- Schwierigkeit
- 4/5
- Geschätzter Aufwand
- 3-5 Tage
- Aktivitätsstatus
- Veraltet
- Klarheit
- Klar beschrieben
- Anfängerfreundlichkeit
- 48/100