Can a non-ReadOnly item in a TypedDict be redeclared as ReadOnly?

Concretely, should the following be allowed?

from typing import TypedDict, ReadOnly

class A(TypedDict):
  x: str

class B(TypedDict):
  x: ReadOnly[str]

def f(b: B) -> None:
  a: A = b

The current assignability rules allow this, but the conformance tests here and here mark it as an error.

I think the conformance tests are correct (the redeclaration would make it possible to write to a read-only field), so I’d like to make the following addition (in bold) to the assignability rules:

  • For each item in A, B has the corresponding key, unless the item in A is read-only, not required, and of top value type (ReadOnly[NotRequired[object]]).
  • For each item in A, if B has the corresponding key, the corresponding value type in B is assignable to the value type in A.
  • For each non-read-only item in A, its value type is assignable to the corresponding value type in B, and the corresponding key is not read-only in B.
  • For each required key in A, the corresponding key is required in B.
  • For each non-required key in A, if the item is not read-only in A, the corresponding key is not required in B.

Feedback welcome =)

7 Likes

Good catch. I agree this is a missing rule.

I think your proposed wording nicely addresses the gap.

This was apparently an omission in the original PEP, and it was copied to the typing spec.

6 Likes

PR has been merged.

1 Like