-
I don't fully understand functions' co/contravariance rules, so perhaps this is nonsense, but to me, these look like they should be treated identically, since from typing import Mapping
from typing import TypedDict
class BqRange(TypedDict):
"""A JSON-compatible representation of the bigquery RANGE<DATETIME> type. Null values indicate an open
https://cloud.google.com/bigquery/docs/reference/standard-sql/data-types#range_type
"""
start: str | None
end: str | None
from typing import Mapping
def bqrange_to_json(x: BqRange) -> Mapping[str, str | None]:
return x
def bqrange_to_json2(x: dict[str, str | None]) -> Mapping[str, str | None]:
return x $ pyright --version
pyright 1.1.379
$ pyright demo.py | sed -r 's#'"$PWD"'/#./#g'
./demo.py
./demo.py:21:12 - error: Type "BqRange" is not assignable to return type "Mapping[str, str | None]"
"BqRange" is not assignable to "Mapping[str, str | None]"
Type parameter "_VT_co@Mapping" is covariant, but "object" is not a subtype of "str | None"
Type "object" is not assignable to type "str | None"
"object" is not assignable to "str"
"object" is not assignable to "None" (reportReturnType)
1 error, 0 warnings, 0 informations |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 5 replies
-
Pyright is working correctly here. A There is a draft PEP 728 that proposes to introduce the concept of a "closed" TypedDict to the Python type system. This PEP hasn't yet been approved by the typing council or the steering council, but pyright implements provisional support for it. |
Beta Was this translation helpful? Give feedback.
-
I hesistate to report it, since it's doing what I want, but it sounds like this is a bug, in that case? def bqrange_to_json3(x: BqRange) -> Mapping[str, IsoTimestamp | None]:
return dict(**x) |
Beta Was this translation helpful? Give feedback.
Pyright is working correctly here. A
TypedDict
class is a structural type that defines specific keys and (if they are present) the corresponding value's type. A dictionary can contain additional keys not specified in a TypedDict definition and still be compatible with the TypedDict. That means the value type in theMapping
must beobject
to account for these possible additional keys. For more details, refer to this portion of the typing spec.There is a draft PEP 728 that proposes to introduce the concept of a "closed" TypedDict to the Python type system. This PEP hasn't yet been approved by the typing council or the steering council, but pyright implements provisional support for it.