I encounter a weird error while defining an immutable list type:
import sys
from re import split
from typing import Tuple, List, NewType
tokens = split("(\d \.\d )", sys.argv[1])
# this works perfectly
# Tokens = NewType("Tokens", List[str])
# print(Tokens(tokens))
# this doesn't work ...
Tokens = NewType("Tokens", Tuple[str])
print(Tokens(tuple(tokens)))
Here is the error that I get:
> mypy main.py
main.py:13: error: Argument 1 to "Tokens" has incompatible type "Tuple[Union[str, Any], ...]"; expected "Tuple[str]"
Found 1 error in 1 file (checked 1 source file)
CodePudding user response:
Why the error occurs
When you using tuple()
to transform a list to tuple, Python
or at least Mypy
doesn't know the exact type of elements in the tuple. Thus the error occurs.
Using different approaches to transform the list to tuple leads to different Mypy error:
token_x = tuple(tokens)
token_y = tuple(i for i in tokens)
token_z = (*tokens, )
main.py:15: error: Argument 1 to "Tokens" has incompatible type "Tuple[Union[str, Any], ...]"; expected "Tuple[str]"
main.py:16: error: Argument 1 to "Tokens" has incompatible type "Tuple[Union[str, Any], ...]"; expected "Tuple[str]"
main.py:17: error: Argument 1 to "Tokens" has incompatible type "Tuple[Any, ...]"; expected "Tuple[str]"
Solution
import sys
from re import split
from typing import Tuple, List, NewType
tokens: List[str] = split("(\d \.\d )", sys.argv[1]) # explicit annotation on here is great but not necessary
token_x = tuple(tokens)
token_y = tuple(i for i in tokens)
token_z = (*tokens,)
# this works perfectly
# Tokens = NewType("Tokens", List[str])
# print(Tokens(tokens))
# this doesn't work ...
Tokens = NewType("Tokens", Tuple[str, ...]) # explicitly annotate with Tuple[str, ...]
Tokens = NewType("Tokens", Sequence[str]) # or using Sequence[str], which is recommended by Mypy offical document
print(Tokens(token_x))
print(Tokens(token_y))
print(Tokens(token_z))
Appendix
Related question: How to annotate function that takes a tuple of variable length? (variadic tuple type annotation)
Meaning of Tuple[str, ...]
: str, ...
stands of all the elements in the tuple are str
Mypy offical Doc: https://mypy.readthedocs.io/en/stable/kinds_of_types.html#tuple-types