pytype вызывает FAILED для функции, использующей TypeVar - PullRequest
0 голосов
/ 05 ноября 2019

Я использую pytype (2019.10.17 , последняя версия до сих пор) в качестве средства проверки типа кода для разработки инструмента, который может произвольно читать файл msgpack с помощью индексного файла, который записывает положение (смещение вфайл msgpack) каждого сообщения (значение хранится в msgpack). Что касается разнообразия типов сообщений, я использую typing.TypeVar для реализации универсального типа. Возникла проблема при работе pytype с TypeVar.

Name: pytype
Version: 2019.10.17
Summary: Python type inferencer
Home-page: https://google.github.io/pytype
Author: None
Author-email: None
License: UNKNOWN
Location: /home/gaoyunpeng/miniconda3/envs/restore/lib/python3.6/site-packages
Requires: ninja, typed-ast, six, importlab, pyyaml, attrs
Required-by:
Python 3.6.4 :: Anaconda, Inc.
from typing import TypeVar
T = TypeVar('T')

def f(x: T): 
  print(x)

запустите указанный выше код с помощью команды: pytype main2.py:

Computing dependencies
Analyzing 1 sources with 0 local dependencies
ninja: Entering directory `/home/gaoyunpeng/workspace/.pytype'
[1/1] check main2
FAILED: /home/gaoyunpeng/workspace/.pytype/pyi/main2.pyi 
pytype-single --imports_info /home/gaoyunpeng/workspace/.pytype/imports/main2.imports --module-name main2 -V 3.6 -o /home/gaoyunpeng/workspace/.pytype/pyi/main2.pyi --analyze-annotated --nofail --quick /home/gaoyunp
eng/workspace/main2.py
File "/home/gaoyunpeng/workspace/main2.py", line 4, in <module>: Invalid type annotation 'T'  [invalid-annotation]
  Appears only once in the signature

For more details, see https://google.github.io/pytype/errors.html#invalid-annotation.
ninja: build stopped: subcommand failed.

Как указано https://google.github.io/pytype/errors.html#invalid-annotation, этот случай является недействительной аннотацией.

Я хочу знать, почему код не может пройти проверку pytype.

1 Ответ

0 голосов
/ 05 ноября 2019

Распечатанное сообщение об ошибке объясняет, почему это ошибка типа. Как говорится в программе. Чтобы процитировать соответствующий фрагмент сообщения об ошибке:

File "/home/gaoyunpeng/workspace/main2.py", line 4, in <module>: Invalid type annotation 'T'  [invalid-annotation]
  Appears only once in the signature

Ошибка использовать TypeVar только один раз в данной сигнатуре, потому что это бессмысленно. В вашем случае вы могли бы просто использовать вместо этого сигнатуру типа def f(x: object) -> None. Вы хотите сказать, что f может принимать все, все в Python является подтипом object.

Вам следует использовать универсальные типы, только если вы хотите, чтобы два или более типа были абсолютно одинаковыми. Например, было бы правильно использовать универсальные типы, если вы хотите определить функцию «identity»:

def identity(x: T) -> T:
    return x

Это позволило бы средству проверки типов сделать вывод, что identity("foo") и identity(4) имеюттипы str и int соответственно - что возвращаемый тип всегда совпадает с типом параметра.

Обратите внимание, что это правило «всегда следует использовать TypeVar два или более раз на подпись», также верно для методов вобщие классы, а также. Когда вы делаете:

class Foo(Generic[T]):
    def test(self, x: T) -> None: pass

... подпись test на самом деле def test(self: Foo[T], x: T) -> None. Таким образом, мы неявно всегда также используем TypeVar дважды.

...