Reputation: 13415
It looks like a dictionary of SomeKeyType
cannot be assigned as a dictionary of objects
, even though all types are subtypes of object
:
x: dict[str, str] = {"a": "b"}
y: dict[object, str] = x
Incompatible types in assignment (expression has type "Dict[str, str]", variable has type "Dict[object, str]")
Copying doesn't help either:
x: dict[str, str] = {"a": "b"}
y: dict[object, str] = dict(x)
Argument 1 to "dict" has incompatible type "Dict[str, str]"; expected "SupportsKeysAndGetItem[object, str]"
A similar error occurs when updating a dictionary of objects
with a dictionary of another type:
x: dict[object, str] = {"a": "a"}
y: dict[str, str] = {"b": "b"}
x.update(y)
x = {**x, **y}
x |= y
Argument 1 to "update" of "dict" has incompatible type "Dict[str, str]"; expected "Mapping[object, str]"
Argument 1 to "update" of "dict" has incompatible type "Dict[str, str]"; expected "Mapping[object, str]"
Argument 1 to "__ior__" of "dict" has incompatible type "Dict[str, str]"; expected "Mapping[object, str]"
Note that a naive implementation of dict.update
does not generate any typing issue:
for k, v in y.items():
x[k] = v
Is that on purpose or is it an issue I should report on the mypy tracker?
Upvotes: 1
Views: 2547
Reputation: 7867
While a str
is an object
, it's not generally true that an F[str]
is an F[object]
for some type constructor F
. For example, a dict[str, ...]
is apparently not a dict[object, ...]
. This is likely because dict[K, V]
is invariant in its key type K
, whereas you'd need it to be covariant. Types are often invariant in a type parameter because the type appears in both method argument and return type positions, like dict.__getitem__(key: K) -> V
and dict.keys() -> KeysView[K]
.
You can fix your code by typing x
as dict[object, str]
. I guess this works because mypy then infers the "a"
as an object
, as opposed to inferring the dict[str, str]
as a dict[object, str]
. Whether that's the best solution for you depends on your context.
See this section of the mypy docs for more info on in-/co-/contravariance.
This discussion looks relevant though I only skimmed it.
Upvotes: 2