← Back to index

typeddicts_readonly_consistency.py

True Positive
False Positive
False Negative
Optional (detected)
Warning or Info
TP: 7
FP: 0
FN: 0
Optional: 0 / 0
1"""
2Tests type consistency rules for TypedDict with ReadOnly items.
3"""
4
5# Specification: https://typing.readthedocs.io/en/latest/spec/typeddict.html#read-only-items
6
7from typing import Any, Collection, NotRequired, Required, TypedDict
8from typing_extensions import ReadOnly
9
10# > A TypedDict type ``A`` is consistent with TypedDict ``B`` if ``A`` is
11# > structurally compatible with ``B``. This is true if and only if all of
12# > the following are satisfied:
14# > For each item in ``B``, ``A`` has the corresponding key, unless the item
15# > in ``B`` is read-only, not required, and of top value type
16# > (``ReadOnly[NotRequired[object]]``).
19class A1(TypedDict):
20 x: Required[int]
23class B1(TypedDict):
24 x: Required[int]
25 y: NotRequired[str]
28class C1(TypedDict):
29 x: Required[int]
30 y: ReadOnly[NotRequired[str]]
33def func1(a: A1, b: B1, c: C1):
34 v1: A1 = b # OK
35 v2: A1 = c # OK
37 v3: B1 = a # E
[invalid-assignment] Object of type `A1` is not assignable to `B1`
38 v4: B1 = c # E
[invalid-assignment] Object of type `C1` is not assignable to `B1`
40 v5: C1 = a # E
[invalid-assignment] Object of type `A1` is not assignable to `C1`
41 v6: C1 = b # OK
44# > For each item in ``B``, if ``A`` has the corresponding key, the
45# > corresponding value type in ``A`` is consistent with the value type in ``B``.
47# (This is the same rule that applies to TypedDicts without read-only items,
48# so we will skip this redundant test.)
50# > For each non-read-only item in ``B``, its value type is consistent with
51# > the corresponding value type in ``A``.
53# (This is the same rule that applies to TypedDicts without read-only items,
54# so we will skip this redundant test.)
56# > For each required key in ``B``, the corresponding key is required in ``A``.
58# (This is the same rule that applies to TypedDicts without read-only items,
59# so we will skip this redundant test.)
61# > For each non-required key in ``B``, if the item is not read-only in ``B``,
62# > the corresponding key is not required in ``A``.
65class A2(TypedDict):
66 x: NotRequired[ReadOnly[str]]
69class B2(TypedDict):
70 x: NotRequired[str]
73class C2(TypedDict):
74 x: Required[str]
77def func2(a: A2, b: B2, c: C2):
78 v1: A2 = b # OK
79 v2: A2 = c # OK
81 v3: B2 = a # E
[invalid-assignment] Object of type `A2` is not assignable to `B2`
82 v4: B2 = c # E
[invalid-assignment] Object of type `C2` is not assignable to `B2`
84 v5: C2 = a # E
[invalid-assignment] Object of type `A2` is not assignable to `C2`
85 v6: C2 = b # E
[invalid-assignment] Object of type `B2` is not assignable to `C2`