I'm using pytype (2019.10.17,latest version up to now) as my code type checker to develop a tool, that is able to read msgpack file randomly by using a index file, which records the position (offset in the msgpack file) of each message (the value stored in msgpack).
In terms of the variety of type of message, I use typing.TypeVar to implement a generic type. A problem was encountered when pytype working with 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)
Run the above code with command: 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.
As https://google.github.io/pytype/errors.html#invalid-annotation stated, this case is an invalid-annotation.
Why can't the code pass the pytype check?
The error message that was printed out explains why this is a type error. As the program says. To quote the relevant piece of the error message:
File "/home/gaoyunpeng/workspace/main2.py", line 4, in <module>: Invalid type annotation 'T' [invalid-annotation]
Appears only once in the signature
It is an error to use a TypeVar only once in a given signature because it's pointless to do so. In your case, you might as well just use the type signature def f(x: object) -> None instead. You want to say that f can accept anything, everything in Python is a subtype of object.
You should be using generic types only if you want to insist two or more types are exactly the same. For example, it'd be correct to use generic types if you wanted to define an "identity" function:
def identity(x: T) -> T:
return x
This would allow the type checker to infer that identity("foo") and identity(4) are of types str and int respectively -- that the return type is always the same as the parameter type.
Note that this "you should always use a TypeVar two or more times per signature" rule is also true for methods in generic classes as well. When you do:
class Foo(Generic[T]):
def test(self, x: T) -> None: pass
...the signature of test is actually def test(self: Foo[T], x: T) -> None. So we're implicitly always using the TypeVar twice there as well.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With