Fix TypedDict in narrowing wrongly eliminating subtype for extra_items keys - #11610
Fix TypedDict in narrowing wrongly eliminating subtype for extra_items keys#11610Nilesh Patil (nileshpatil6) wants to merge 2 commits into
Conversation
…ems keys In narrowTypeForTypedDictKey the negative branch treated a key that only matched the extra_items pseudo-entry the same as a known item, so for a closed TypedDict with extra_items a check like 'if "key" in td' made the else branch unreachable. An extra item may or may not be present, so only a known required or provided item can eliminate the subtype.
|
🔒 Automated review in progress — Stella Huang (@StellaHuang95) is auto-reviewing this PR. |
|
|
||
| # This should generate a type incompatibility error. If the statements | ||
| # above are incorrectly marked unreachable, no error is reported here. | ||
| movie["other3"] = 1 |
There was a problem hiding this comment.
Warning · Non-blocking recommendation
Please also cover a negative in check on a known required key (such as name) and assert that its following code remains unreachable. This would protect the existing narrowing behavior against an accidental over-relaxation of this change. [verified]
Stella Huang (StellaHuang95)
left a comment
There was a problem hiding this comment.
Approved via Review Center.
|
Good call. Added in f379f89: a negative Also sanity checked it guards what you had in mind: if I over-relax the fix to return the subtype unconditionally in the negative branch, TypedDictClosed1 fails on exactly this case; with the fix as written, all 10 TypedDictClosed tests pass. |
Stella Huang (StellaHuang95)
left a comment
There was a problem hiding this comment.
Approved via Review Center.
Rich Chiodo (rchiodo)
left a comment
There was a problem hiding this comment.
Approved via Review Center.
Rich Chiodo (rchiodo)
left a comment
There was a problem hiding this comment.
Approved via Review Center.
For a TypedDict with
extra_items(PEP 728), a membership check on a key that is not a known item wrongly makes the negative branch unreachable:The cause is in
narrowTypeForTypedDictKey: the negative branch usedknownItems.get(key) ?? extraItems, so a key that only matched the extra_items pseudo-entry was treated like a known provided item and eliminated the subtype. An extra item may or may not be present at runtime, so its absence can never rule the type out. Only a known item that is required or provided can do that.The positive branch keeps its current behavior, it still uses the extra_items entry to mark the key as provided after the check.
Testing: added a case to
typedDictClosed1.pywhere code after a negativeincheck on an extra key must stay reachable (it asserts an unrelated type error is still reported there, which the unreachability bug swallows). Without the fix that sample reports 7 errors instead of 8, with it all 10 TypedDictClosed tests pass and the full typeEvaluator suite is green: 1184 tests across 8 suites, 0 failures.