Skip to content

Conversation

@mtshiba
Copy link
Contributor

@mtshiba mtshiba commented Oct 9, 2025

Summary

This PR allows any string Literal type expression to be used as a key when constructing a TypedDict.

The pattern of reusing constant key strings when constructing a TypedDict seems to be common in several libraries (e.g., home-assistant/core).
Currently, we only accept string literal keys when constructing a TypedDict, but any expression that can be inferred to be of type string Literal is also acceptable. In fact, the spec explicitly states that Literal type expressions and Final names ​​should be allowed.

Test Plan

New tests in typed_dict.md

@github-actions
Copy link
Contributor

github-actions bot commented Oct 9, 2025

Diagnostic diff on typing conformance tests

No changes detected when running ty on typing conformance tests ✅

@github-actions
Copy link
Contributor

github-actions bot commented Oct 9, 2025

mypy_primer results

Changes were detected when running on open source projects
core (https://github.com/home-assistant/core)
- homeassistant/components/dhcp/__init__.py:228:33: error[missing-typed-dict-key] Missing required key 'hostname' in TypedDict `DHCPAddressData` constructor
- homeassistant/components/dhcp/__init__.py:228:33: error[missing-typed-dict-key] Missing required key 'ip' in TypedDict `DHCPAddressData` constructor
- homeassistant/components/meteo_france/weather.py:194:21: error[missing-typed-dict-key] Missing required key 'datetime' in TypedDict `Forecast` constructor
- homeassistant/components/meteo_france/weather.py:216:21: error[missing-typed-dict-key] Missing required key 'datetime' in TypedDict `Forecast` constructor
- homeassistant/components/nws/weather.py:250:30: error[missing-typed-dict-key] Missing required key 'datetime' in TypedDict `Forecast` constructor
- homeassistant/components/nws/weather.py:306:35: error[missing-typed-dict-key] Missing required key 'datetime' in TypedDict `ExtraForecast` constructor
- homeassistant/components/p1_monitor/coordinator.py:73:31: error[missing-typed-dict-key] Missing required key 'smartmeter' in TypedDict `P1MonitorData` constructor
- homeassistant/components/p1_monitor/coordinator.py:73:31: error[missing-typed-dict-key] Missing required key 'phases' in TypedDict `P1MonitorData` constructor
- homeassistant/components/p1_monitor/coordinator.py:73:31: error[missing-typed-dict-key] Missing required key 'settings' in TypedDict `P1MonitorData` constructor
- homeassistant/components/p1_monitor/coordinator.py:73:31: error[missing-typed-dict-key] Missing required key 'watermeter' in TypedDict `P1MonitorData` constructor
- homeassistant/components/tcp/entity.py:40:41: error[missing-typed-dict-key] Missing required key 'name' in TypedDict `TcpSensorConfig` constructor
- homeassistant/components/tcp/entity.py:40:41: error[missing-typed-dict-key] Missing required key 'host' in TypedDict `TcpSensorConfig` constructor
- homeassistant/components/tcp/entity.py:40:41: error[missing-typed-dict-key] Missing required key 'port' in TypedDict `TcpSensorConfig` constructor
- homeassistant/components/tcp/entity.py:40:41: error[missing-typed-dict-key] Missing required key 'timeout' in TypedDict `TcpSensorConfig` constructor
- homeassistant/components/tcp/entity.py:40:41: error[missing-typed-dict-key] Missing required key 'payload' in TypedDict `TcpSensorConfig` constructor
- homeassistant/components/tcp/entity.py:40:41: error[missing-typed-dict-key] Missing required key 'unit_of_measurement' in TypedDict `TcpSensorConfig` constructor
- homeassistant/components/tcp/entity.py:40:41: error[missing-typed-dict-key] Missing required key 'value_template' in TypedDict `TcpSensorConfig` constructor
- homeassistant/components/tcp/entity.py:40:41: error[missing-typed-dict-key] Missing required key 'value_on' in TypedDict `TcpSensorConfig` constructor
- homeassistant/components/tcp/entity.py:40:41: error[missing-typed-dict-key] Missing required key 'buffer_size' in TypedDict `TcpSensorConfig` constructor
- homeassistant/components/tcp/entity.py:40:41: error[missing-typed-dict-key] Missing required key 'ssl' in TypedDict `TcpSensorConfig` constructor
- homeassistant/components/tcp/entity.py:40:41: error[missing-typed-dict-key] Missing required key 'verify_ssl' in TypedDict `TcpSensorConfig` constructor
- homeassistant/components/todoist/calendar.py:130:37: error[missing-typed-dict-key] Missing required key 'name' in TypedDict `ProjectData` constructor
- homeassistant/components/todoist/calendar.py:130:37: error[missing-typed-dict-key] Missing required key 'id' in TypedDict `ProjectData` constructor
- homeassistant/components/todoist/calendar.py:170:37: error[missing-typed-dict-key] Missing required key 'name' in TypedDict `ProjectData` constructor
- homeassistant/components/todoist/calendar.py:170:37: error[missing-typed-dict-key] Missing required key 'id' in TypedDict `ProjectData` constructor
- homeassistant/components/todoist/calendar.py:528:30: error[missing-typed-dict-key] Missing required key 'all_day' in TypedDict `TodoistEvent` constructor
- homeassistant/components/todoist/calendar.py:528:30: error[missing-typed-dict-key] Missing required key 'completed' in TypedDict `TodoistEvent` constructor
- homeassistant/components/todoist/calendar.py:528:30: error[missing-typed-dict-key] Missing required key 'description' in TypedDict `TodoistEvent` constructor
- homeassistant/components/todoist/calendar.py:528:30: error[missing-typed-dict-key] Missing required key 'due_today' in TypedDict `TodoistEvent` constructor
- homeassistant/components/todoist/calendar.py:528:30: error[missing-typed-dict-key] Missing required key 'end' in TypedDict `TodoistEvent` constructor
- homeassistant/components/todoist/calendar.py:528:30: error[missing-typed-dict-key] Missing required key 'labels' in TypedDict `TodoistEvent` constructor
- homeassistant/components/todoist/calendar.py:528:30: error[missing-typed-dict-key] Missing required key 'overdue' in TypedDict `TodoistEvent` constructor
- homeassistant/components/todoist/calendar.py:528:30: error[missing-typed-dict-key] Missing required key 'priority' in TypedDict `TodoistEvent` constructor
- homeassistant/components/todoist/calendar.py:528:30: error[missing-typed-dict-key] Missing required key 'start' in TypedDict `TodoistEvent` constructor
- homeassistant/components/todoist/calendar.py:528:30: error[missing-typed-dict-key] Missing required key 'summary' in TypedDict `TodoistEvent` constructor
- homeassistant/components/todoist/calendar.py:552:21: error[unsupported-operator] Operator `in` is not supported for types `Unknown` and `bool`, in comparing `Unknown` with `Unknown | bool | str | ... omitted 3 union elements`
- homeassistant/components/todoist/calendar.py:570:21: error[unsupported-operator] Operator `>` is not supported for types `bool` and `datetime`, in comparing `Unknown | bool | str | ... omitted 3 union elements` with `datetime`
+ homeassistant/components/todoist/calendar.py:570:21: error[unsupported-operator] Operator `>` is not supported for types `None` and `datetime`, in comparing `datetime | None` with `datetime`
- homeassistant/components/todoist/calendar.py:576:35: warning[possibly-missing-attribute] Attribute `date` on type `Unknown | bool | str | ... omitted 3 union elements` may be missing
+ homeassistant/components/todoist/calendar.py:576:35: warning[possibly-missing-attribute] Attribute `date` on type `datetime | None` may be missing
+ homeassistant/components/todoist/calendar.py:579:20: error[unsupported-operator] Operator `<=` is not supported for types `None` and `datetime`, in comparing `datetime | None` with `datetime`
- homeassistant/components/todoist/calendar.py:579:20: error[unsupported-operator] Operator `<=` is not supported for types `bool` and `str`, in comparing `Unknown | bool | str | ... omitted 3 union elements` with `Unknown | bool | str | ... omitted 3 union elements`
- homeassistant/components/todoist/calendar.py:584:33: error[unsupported-operator] Operator `+` is unsupported between objects of type `Unknown | bool | str | ... omitted 3 union elements` and `timedelta`
- homeassistant/core.py:1965:45: error[missing-typed-dict-key] Missing required key 's' in TypedDict `CompressedState` constructor
- homeassistant/core.py:1965:45: error[missing-typed-dict-key] Missing required key 'a' in TypedDict `CompressedState` constructor
- homeassistant/core.py:1965:45: error[missing-typed-dict-key] Missing required key 'c' in TypedDict `CompressedState` constructor
- homeassistant/core.py:1965:45: error[missing-typed-dict-key] Missing required key 'lc' in TypedDict `CompressedState` constructor
- Found 13736 diagnostics
+ Found 13695 diagnostics
No memory usage changes detected ✅

@AlexWaygood AlexWaygood added the ty Multi-file analysis & type inference label Oct 9, 2025
@mtshiba mtshiba marked this pull request as ready for review October 9, 2025 18:05
Copy link
Member

@AlexWaygood AlexWaygood left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great -- thank you!

@AlexWaygood AlexWaygood enabled auto-merge (squash) October 9, 2025 18:19
@AlexWaygood AlexWaygood merged commit db91ac7 into astral-sh:main Oct 9, 2025
39 checks passed
@mtshiba mtshiba deleted the typed-dict-key-expr branch October 9, 2025 18:28
@ibraheemdev
Copy link
Member

In fact, the spec explicitly states that Literal type expressions and Final names ​​should be allowed.

FWIW I think the spec only states this for TypedDict operations, not definitions, but I agree that we should support this anyways as it's common in the ecosystem.

I think we can also update our bidirectional inference code, which makes the same assumption.

carljm pushed a commit that referenced this pull request Oct 10, 2025
…ucting a `TypedDict` (#20806)

## Summary

Based on @ibraheemdev's comment on #20792:

> I think we can also update our bidirectional inference code, [which
makes the same
assumption](https://github.com/astral-sh/ruff/blob/main/crates/ty_python_semantic/src/types/infer/builder.rs?rgh-link-date=2025-10-09T21%3A30%3A31Z#L5860).

This PR also adds more test cases for how `TypedDict` annotations affect
generic call inference.

## Test Plan

New tests in `typed_dict.md`
@mtshiba mtshiba mentioned this pull request Oct 14, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ty Multi-file analysis & type inference

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants