Во время устранения неполадок, связанных с частично связанной проблемой в Python чате , я обнаружил в mypy поведение, которое я не понимаю.
from typing import Union, List, Dict
def f(x: Union[
Dict[str, float],
Dict[str, str],
Dict[str, int],
]):
pass
f({"a": 1}) #passes
f({"a": "b"}) #passes
f({"a": 1.0}) #passes
def g(x: Union[
Dict[str, float],
Dict[str, Union[str, int]],
]):
pass
g({"a": 1}) #fails
g({"a": "b"}) #fails
g({"a": 1.0}) #passes
def h(x: Dict[str, Union[float, str, int]]):
pass
h({"a": 1}) #passes
h({"a": "b"}) #passes
h({"a": 1.0}) #passes
Когда я выполняю mypy в этом скрипте он жалуется только на среднюю функцию, g
:
C:\Users\Kevin\Desktop>mypy test.py
test.py:20: error: Argument 1 to "g" has incompatible type "Dict[str, int]"; expected "Union[Dict[str, float], Dict[str, Union[str, int]]]"
test.py:20: note: "Dict" is invariant -- see http://mypy.readthedocs.io/en/latest/common_issues.html#variance
test.py:20: note: Consider using "Mapping" instead, which is covariant in the value type
test.py:21: error: Argument 1 to "g" has incompatible type "Dict[str, str]"; expected "Union[Dict[str, float], Dict[str, Union[str, int]]]"
test.py:21: note: "Dict" is invariant -- see http://mypy.readthedocs.io/en/latest/common_issues.html#variance
test.py:21: note: Consider using "Mapping" instead, which is covariant in the value type
Found 2 errors in 1 file (checked 1 source file)
(как следует из примечаний, замена Dict
на Mapping
удаляет ошибки, но, скажем, ради вопрос, что я должен использовать Dict.)
Эти ошибки меня удивляют. Насколько я могу судить, аннотации типов для каждой функции должны упроститься до той же группы типов: dict, ключи которого являются строками, а значения - числами с плавающей запятой / строками / целыми числами. Так почему только g
имеет несовместимые типы? Mypy как-то смущает наличие двух Союзов?