Python typehint для os.getenv вызывает ошибки несовместимого типа в нисходящем направлении - PullRequest
1 голос
/ 18 февраля 2020

При использовании os.getenv для извлечения переменных среды поведение по умолчанию возвращает тип Optional[str]. Это проблематично c, поскольку любые последующие методы / функции, использующие эти переменные, вероятно, будут определены для явного принятия типа str. Есть ли допустимое использование, чтобы обойти эту проблему или принудительно применить тип возврата str?

В определении файла-заглушки для getenv в typhed вы можете обнаружите, что getenv может иметь тип возврата Optional[str] или Union[str, T_] в зависимости от использования default kwarg.

Четыре варианта, которые я пока вижу:

  1. Определите любые последующие операции для принятия типов Optional[str] в качестве аргументов. Это не кажется особенно правильным, поскольку функция / метод не может быть структурирована таким образом, чтобы тип Optional имел смысл. т. е. операция не имеет причины для определенного аргумента None.
  2. . Используйте default kwarg для getenv и укажите значение str по умолчанию. Это кажется более правильным, но требует, чтобы каждый устанавливал значение по умолчанию для каждого использования getenv. Единственная проблема, которую я вижу в этом, заключается в том, что это может мешать тестированию или использованию в разных средах.
  3. Определить какую-то функцию проверки переменных. Это может быть функция, которая принимает имя переменной среды для загрузки, явно возвращает строку и выдает ошибку, если переменная среды не существует.
  4. Явно устанавливает тип значения, возвращаемого getenv быть ул. Мне действительно это не нравится, так как ожидается, что среда всегда будет правильно настроена, что, по моему опыту, не очень хорошее предположение.

Ниже приведен пример, приводящий к ошибке 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)

Приведенное выше вызывает ошибку mypy:

error: аргумент 1 для "some_fun c" имеет несовместимый тип "Optional [str]"; ожидаемая "ул"

Ответы [ 2 ]

1 голос
/ 18 февраля 2020

tl; dr Используйте os.environ['SOME_VAR'], если вы уверены, что он всегда есть


os.getenv может и возвращает None - mypy помогает в показывая, что у вас есть ошибка:

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

В качестве альтернативы, вы можете убедить mypy, что вы ожидаете его двумя разными способами:

  1. используя утверждения:
x = os.getenv('SOME_VAR')
assert x is not None, x
# mypy will believe that it is non-None after this point

с использованием приведения:

from typing import cast

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

(у приведения есть некоторые недостатки, которые никогда не проверяются, тогда как утверждение, мы надеемся, приведет к провалу теста)

Я бы предложил не игнорировать эту ошибку / обойти ее и вместо этого использовать os.environ['SOME_VAR'] для вещей, которые вы ожидаете всегда иметь, или написать условие для проверки на случай ошибки, когда она отсутствует

0 голосов
/ 18 февраля 2020

SOME_VAR является необязательным, поскольку может быть None

Возвращать значение переменной среды varname, если оно существует, или значение, если его нет. значение по умолчанию Нет.

Документы

Вы можете установить запасной вариант, если переменная среды не существует:

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)

Это должно сделать SOME_VAR "необязательным"

...