10 votes

Python typehint for os.getenv cause des erreurs de type incompatible en aval

Lorsque vous utilisez os.getenv pour récupérer des variables d'environnement, le comportement par défaut renvoie un type de Optional[str] . Cela pose un problème car toutes les méthodes/fonctions en aval qui utilisent ces variables seront probablement définies pour accepter une variable str de manière explicite. Existe-t-il une utilisation acceptée pour contourner ce problème ou pour faire respecter l'obligation d'information ? str type de retour ?

Dans la définition du fichier stub pour getenv sur typeshed vous pouvez trouver que getenv peut avoir un type de retour de Optional[str] ou Union[str, T_] en fonction de l'utilisation de la default kwarg.

Les quatre options que je vois pour l'instant sont les suivantes :

  1. Définir toute opération en aval à accepter Optional[str] en tant qu'arguments. Cela ne semble pas particulièrement correct, car une fonction/méthode peut ne pas être structurée de manière à ce que l'outil d'évaluation de l'impact sur l'environnement soit utilisé. Optional a un sens, c'est-à-dire que l'opération n'a aucune raison pour qu'un argument particulier soit None .
  2. Utilisez le default kwarg pour getenv et fournir un str valeur par défaut. Cela semble plus correct, mais exige que l'on définisse une valeur par défaut pour chaque utilisation de l'option getenv . Le seul problème que je vois dans cette démarche est qu'elle peut être source de confusion pour les tests ou l'utilisation dans des environnements différents.
  3. Définissez une sorte de fonction de vérification des variables. Il peut s'agir d'une fonction qui accepte le nom d'une variable d'environnement à charger, renvoie explicitement une chaîne de caractères et génère une erreur si la variable d'environnement n'existe pas.
  4. Définir explicitement le type de la valeur retournée par getenv pour être un str. Je n'aime vraiment pas cela, car cela suppose que l'environnement est toujours correctement configuré, ce qui, d'après mon expérience, n'est pas une bonne supposition.

Trouvez ci-dessous un exemple qui soulève une erreur mypy.

import os

SOME_VAR = os.getenv("SOME_VAR")

def some_func(val: str) -> None:
    print(f"Loaded env var: {val}")

some_func(SOME_VAR)

Ce qui précède soulève l'erreur mypy :

erreur : L'argument 1 de "some_func" est d'un type incompatible "Optional[str]" ; on attendait "str".

13voto

Anthony Sottile Points 3629

en résumé Utilisez os.environ['SOME_VAR'] si tu es sûr que c'est toujours là.


os.getenv peut revenir et revient effectivement None -- mypy est utile en montrant que vous avez un bug ici :

>>> repr(os.getenv('DOES_NOT_EXIST'))
'None'
>>> repr(os.getenv('USER'))
"'asottile'"

Vous pouvez également convaincre mypy qu'il est du type que vous attendez de deux manières différentes :

  1. en utilisant des assertions :

    x = os.getenv('SOME_VAR') assert x is not None, x

    mypy will believe that it is non-None after this point

  2. en utilisant un plâtre :

    from typing import cast
    
    x = cast(str, os.getenv('SOME_VAR'))
    # mypy will believe that it is a `str` after this point

(le cast a quelques inconvénients dans la mesure où il n'est jamais vérifié, alors que l'assertion conduira, on l'espère, à un échec du test)

Je suggère no ignorer cette erreur / la contourner et utiliser plutôt os.environ['SOME_VAR'] pour les éléments qui devraient toujours être présents, ou écrire une condition pour vérifier le cas d'erreur lorsqu'ils sont manquants.

0voto

Sven Fritsch Points 76

SOME_VAR est facultatif car il peut être None

Retourne la valeur de la variable d'environnement varname si elle existe, ou value si elle n'existe pas. value a la valeur None par défaut.

Docs

Vous pourriez définir une solution de repli si la variable d'environnement n'existe pas :

import os

SOME_VAR = os.getenv("SOME_VAR", "my fallback value")

def some_func(val: str) -> None:
    print(f"Loaded env var: {val}")

some_func(SOME_VAR)

Cela devrait faire SOME_VAR "non facultatif"

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X