False positive `reportTypedDictNotRequiredAccess` when indexing `TypedDict` after `if key in typed_dict` guard inside a `Literal` loop
- Dominant language
- Python
- Stars
- 15.6k
- Forks
- 1.8k
- Avg merge
- 12h 13m
- Merged PRs (30d)
- 52
Description
#### **Environment**
- **Pyright Version**: 1.1.411
- **Python Version**: 3.13.14
---
#### **Bug Description**
When iterating over a tuple of string literal keys (e.g. `for key in ("anyOf", "oneOf"):`) and guarding a key lookup on a `total=False` (or `NotRequired`) `TypedDict` using `if key in typed_dict:`, Pyright fails to perform type narrowing on `typed_dict[key]`.
Instead, Pyright raises a false positive `reportTypedDictNotRequiredAccess` warning:
```text
Could not access item in TypedDict
"anyOf" is not a required key in "JsonSchema", so access may result in runtime exception
"oneOf" is not a required key in "JsonSchema", so access may result in runtime exception
```
Even though `if key in typed_dict:` guarantees at runtime that `key` exists before indexing `typed_dict[key]`, Pyright fails to apply narrowing when `key` is a union of literal string types.
---
#### **Minimal Code Example (Repro)**
[pyright playground](https://pyright-play.net/?code=GYJw9gtgBALgngBwJYDsDmUkQWEMoAqiApgCYAiSAxjAFD1UA2AhgM6tQBSrYKAylQAWxCMwAURBGUo0ANLDAxmjALwAxZa2IBKAFy0oUZijgB5YLqiMkrGAG0A5N14DhohwF0DUXsXOXrW0dnfiERZk96WlJiYCgEcCpidgB9VjDRMXS3ZksQ13DtKABaAD4oADlffUNgXCgAa2I4AHdcUkwUKDEAImMzYB75Ht9zHr1vQyQ4ptb2zqhs8JrDVZBiADdiZRT4KTFZtpBSIqgAYkISHziew-aezA4egBkkGGIQZUd%2B8wd5B1GwE8PUmq1YAFcAEZpDJsKAqRawux3Y4eQwXdY4PCSaTUGBVGAAJWIAEdwUh1qQAIJUJLsUGGBKoGBiRjEFBZKEwnKsbTaWhAA)
```python
from typing import TypedDict
class JsonSchema(TypedDict, total=False):
anyOf: list['JsonSchema']
oneOf: list['JsonSchema']
def process_schema(schema: JsonSchema) -> None:
for keyword in ("anyOf", "oneOf"):
if keyword in schema:
reveal_type(keyword) # Type of "keyword" is "Literal['anyOf', 'oneOf']"
sub_schemas = schema[keyword] # reportTypedDictNotRequiredAccess
print(len(sub_schemas))
```
---
#### **Expected Behavior**
Pyright should recognize `if keyword in schema:` as a valid narrowing guard for `TypedDict` keys when `keyword` is a `Literal["anyOf", "oneOf"]` (or a `str` union of valid `TypedDict` keys), permitting safe indexing `schema[keyword]`.
Contributor guide
Research direction
Reproduce the example in the linked Pyright playground, then locate the implementation of reportTypedDictNotRequiredAccess and existing TypedDict narrowing tests. Add a regression case for a Literal-key loop guarded by `if keyword in schema`, and run the relevant type-checker tests to confirm the warning is no longer reported while unsafe access remains diagnosed.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- devtools
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 68/100