python / python/typeshed

Implications of Union in argparse.Action.__call__ parameter types

Ouverte
#7,559 1 commentaire 0 réactions 0 personnes assignées Voir sur GitHub

Personne n'a encore pris cette issue.

Langage dominant
Python
Étoiles
5.1k
Forks
2.1k
Merge moyen
1 j 19 h
PR mergées (30 j)
82

Description

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.

Guide de contribution

Ouvrir le guide de contribution

Par où commencer

  1. Lisez l'issue en entier, puis le guide de contribution du projet.
  2. Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
  3. Forkez le dépôt et travaillez sur une branche.
  4. Ouvrez une pull request qui référence le numéro de l'issue.

Piste de recherche

Examinez d’abord stdlib/argparse.pyi aux lignes 364-366 ainsi que la discussion liée sur Union dans les interfaces de bibliothèques. Comparez l’exemple de callback Action avec l’exemple de type= et déterminez si le stub doit être modifié ou si l’annotation existante doit être documentée ; la tâche n’est terminée qu’avec une résolution approuvée par un maintainer.

Rédigé par le modèle d'indexation à partir du texte de l'issue.

Évaluation

Stack technique
python
Domaine
tooling
Type d'issue
Bug
Difficulté
5/5
Temps estimé
Plus d'une semaine
Activité
À l'abandon
Clarté
À clarifier
Accessibilité débutants
25/100

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.