Implications of Union in argparse.Action.__call__ parameter types
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
https://github.com/python/typeshed/blob/c41034c3540c5abda10008dd6c17d8e6ff6cc634/stdlib/argparse.pyi#L364-L366
I'm wondering if the reasoning behind this choice has been discussed before. Return types of library functions generally avoid Union (python/mypy#1693). To me, the parameters of a user-provided callback are similar to the return type of a library function—the annotations reflect objects passed to user code, and the user may have runtime control of their types. It is, however, more removed from the runtime context because the class must be first defined and then referenced.
If I override __call__ with an implementation that will only ever see str:
import argparse
class CSVCallback(argparse.Action):
def __call__(self, parser, namespace, values, option_string=None):
setattr(namespace, self.dest, list(values.split(',')))
parser = argparse.ArgumentParser()
parser.add_argument('-o', action=CSVCallback, default=[])
args = parser.parse_args()
pyright complains, based on what appears to be a correct interpretation of the stub:
repr.py:5:51 - error: Cannot access member "split" for type "Sequence[Any]"
Member "split" is unknown (reportGeneralTypeIssues)
repr.py:5:51 - error: "split" is not a known member of "None" (reportOptionalMemberAccess)
Would the appropriate solution be to add assert isinstance(values, str) at the beginning of every callback? Or is this actually abuse of action=..., which should be replaced with type=..., like this?
def csv_callback(value: str) -> list[str]:
return list(value.split(','))
parser.add_argument('-o', type=csv_callback, default=[])
Since these examples are based on 10-year-old optparse code that was ported 1:1 to argparse 2 years ago, I'm not considering reimplementing them like that—they aren't broken, and the less trivial examples reference parser.error and the previous value of self.dest. But I'd rather avoid the asserts, so for new code I would probably prefer that pattern.
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
Prüfe zuerst stdlib/argparse.pyi in den Zeilen 364-366 sowie die verknüpfte Diskussion über Union in Bibliotheksschnittstellen. Vergleiche das Beispiel für den Action-Callback mit dem Beispiel für type= und bestimme, ob der Stub geändert oder die vorhandene Annotation dokumentiert werden sollte; abgeschlossen ist die Aufgabe erst mit einer von einem Maintainer genehmigten Lösung.
Vom Indexierungsmodell aus dem Issue-Text verfasst.
Bewertung
- Tech-Stack
- python
- Bereich
- tooling
- Issue-Typ
- Bug
- Schwierigkeit
- 5/5
- Geschätzter Aufwand
- Über eine Woche
- Aktivitätsstatus
- Veraltet
- Klarheit
- Muss geklärt werden
- Anfängerfreundlichkeit
- 25/100