Проблема с хинтингом Python и стандартными библиотеками - PullRequest
0 голосов
/ 04 марта 2020

Следующий код работает, как и ожидалось, но os.path.join выдает ошибку типа, используя pyright в VSCode, где показано.

# python 3.6.9
# pyright 1.1.25
# windows 10
# vscode 1.42.1
import os
import tempfile

with tempfile.TemporaryDirectory() as tmpfolder:
    name = "hello.txt"
    path = os.path.join(tmpfolder, name)
    # No overloads for 'os.path.join(tmpfolder, name)' match parameters
    #   Argument types: (TypeVar['AnyStr', str, bytes], Literal['hello.txt'])

print(path)

Мне кажется, я понимаю непосредственную причину проблемы, но утверждать, что это не должно происходить. Учитывая это, у меня есть несколько вопросов:

  1. Это идиоматический c способ написания этого кода?
  2. Проблема в tempfile, os, pyright или мне?
  3. Если я не могу обновить Python, каков наилучший (т.е. наименее неуклюжий) способ устранения ошибки?

1 Ответ

0 голосов
/ 04 марта 2020

Это похоже на ограничение pyright.

Короче говоря, tempfile.TemporaryDirectory class набирается , чтобы быть обобщенным c относительно AnyStr. Однако в вашем примере кода не указывается тип generi c, а средство проверки типов остается на своем усмотрении.

В этом случае я думаю, что для проверки типов есть несколько разумных вещей:

  1. Выберите некоторый тип по умолчанию универсального c на основе typevar, такой как 'str' или 'Union [str, bytes]'. Например, mypy заканчивает тем, что по умолчанию выбирает «str», давая «tmpfolder» тип «str».
  2. Выберите некоторый тип заполнителя, например «Any», тип Dynami c или NoReturn ( ака «снизу» ака «ничего»). Оба типа являются допустимыми подтипами каждого типа, поэтому гарантированно являются допустимыми заполнителями и не вызывают последующих ошибок. Это то, что делают pyre и pytype - они выводят, что 'tmpfolder' имеет тип 'Any' и 'nothing' соответственно.
  3. Попытка вывести правильный тип на основе контекста. Некоторые средства проверки типов могут пытаться сделать это, но я не знаю ни одного, который бы прекрасно справлялся с этим конкретным случаем.
  4. Сообщите об ошибке и попросите пользователя указать требуемый тип generi c.

Вместо этого pyright, похоже, просто «утечка» переменной generi c. Возможно, есть принципиальная причина, по которой Pyright решает сделать это, но я пропускаю это, но IMO это похоже на ошибку.


Чтобы ответить на другие ваши вопросы, ваша программа-пример - idiomati c Python, и средства проверки типов должны в идеале поддерживать его без изменений.

Добавление комментария # type: ignore к строке с ошибкой - это санкционированный PEP 484 способ подавления сообщений об ошибках. Я не достаточно знаком с Pyright, чтобы знать, есть ли у него другой предпочтительный способ подавления ошибок.

...