microsoft / microsoft/pyright

Unexpected assignability rules of generic TypedDicts

Open
#10,926 0 comments 0 reactions 0 assignees View on GitHub
bug
Dominant language
Python
Stars
15.6k
Forks
1.8k
Avg merge
12h 13m
Merged PRs (30d)
52

Description

When generic TypedDict variable is assigned to (nominally) another TypedDict it looks like assignability rules of `ReadOnly` apply and attribute is treated as covariant. But in case the assignment is made to another generic specialization of nominally same `TypedDict` attribute is treated as invariant.

```python
from typing import TypedDict, ReadOnly

class A: pass
class B(A): pass

class TD0[T](TypedDict):
v: ReadOnly[T]

class TD1[T](TypedDict):
v: ReadOnly[T]

def foo(td: TD0[B]) -> TD0[A]:
return td # Type parameter "T@TD0" is invariant, but "B" is not the same as "A"

def bar(td: TD0[B]) -> TD1[A]:
return td # OK
```

Code sample in [pyright playground](https://pyright-play.net/?enableExperimentalFeatures=true&code=GYJw9gtgBALgngBwJYDsDmUkQWEMoAqiApgCYAiSAxjADRQBKxAhqQPIoA2cAUD1Z2YBnIVACCALigJhQ-oJFQAQgAoxASikzFfAbMLkADAG0CAXRVEEZSjU08ojqADcpTVh26mzuhaILkAIzeliQU1DD2Ti5uLOxccN58pMTAUMBgYCowpFIBJkpm6lAAtAB8BiZiZhIOTiDEMACuICiwpMmpUABGzCDZuZXGhcXlBsHVtdENza3tUHxAA)

Contributor guide

Open the contributing guide

Research direction

Run the linked pyright playground with experimental features enabled and reproduce the differing assignments in foo and bar. Compare the generic TypedDict and ReadOnly cases, then establish consistent assignability behavior for the two nominally related specializations.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
compilers
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
38/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.