Skip to content

[ty] Synthesize TypedDict constructors via __new__#23936

Draft
charliermarsh wants to merge 3 commits intomainfrom
charlie/t1
Draft

[ty] Synthesize TypedDict constructors via __new__#23936
charliermarsh wants to merge 3 commits intomainfrom
charlie/t1

Conversation

@charliermarsh
Copy link
Member

Summary

This PR synthesizes a constructor for TypedDict, which moves constructor checking onto the normal callable machinery (keeps generic-alias specialization intact, preserves TypedDict-specific validation/diagnostics, etc.).

Closes astral-sh/ty#3027.

@astral-sh-bot astral-sh-bot bot added the ty Multi-file analysis & type inference label Mar 13, 2026
@astral-sh-bot
Copy link

astral-sh-bot bot commented Mar 13, 2026

Typing conformance results

No changes detected ✅

Current numbers
The percentage of diagnostics emitted that were expected errors held steady at 85.29%. The percentage of expected errors that received a diagnostic held steady at 78.13%. The number of fully passing files held steady at 64/132.

@astral-sh-bot
Copy link

astral-sh-bot bot commented Mar 13, 2026

mypy_primer results

Changes were detected when running on open source projects
altair (https://github.com/vega/altair)
- altair/vegalite/v6/api.py:699:71: warning[unused-type-ignore-comment] Unused blanket `type: ignore` directive
+ altair/vegalite/v6/api.py:1015:25: error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `_Conditional[list[_ConditionClosed]]`, found `_Conditional[_C@_Conditional]`
+ altair/vegalite/v6/api.py:1017:25: error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `_Conditional[list[_ConditionClosed]]`, found `_Conditional[_C@_Conditional]`
+ altair/vegalite/v6/api.py:1200:16: error[invalid-return-type] Return type does not match returned value: expected `_Conditional[_C@Then]`, found `_Conditional[_C@_Conditional]`
+ tests/vegalite/v6/test_theme.py:220:17: error[invalid-key] Unknown key "guide-label" for TypedDict `StyleConfigIndexKwds`
+ tests/vegalite/v6/test_theme.py:225:17: error[invalid-key] Unknown key "guide-title" for TypedDict `StyleConfigIndexKwds`
+ tests/vegalite/v6/test_theme.py:250:17: error[invalid-key] Unknown key "guide-label" for TypedDict `StyleConfigIndexKwds`
+ tests/vegalite/v6/test_theme.py:251:17: error[invalid-key] Unknown key "guide-title" for TypedDict `StyleConfigIndexKwds`
+ tests/vegalite/v6/test_theme.py:995:13: error[invalid-key] Unknown key "path" for TypedDict `ConfigKwds`
- tests/vegalite/v6/test_theme.py:1012:35: warning[unused-type-ignore-comment] Unused blanket `type: ignore` directive
- Found 1070 diagnostics
+ Found 1076 diagnostics

core (https://github.com/home-assistant/core)
- homeassistant/components/adguard/entity.py:63:25: error[invalid-argument-type] Invalid argument to key "identifiers" with declared type `set[tuple[str, str]]` on TypedDict `DeviceInfo`: value of type `set[tuple[str, Unknown, Unknown, Unknown]]`
+ homeassistant/components/adguard/entity.py:63:25: error[invalid-argument-type] Invalid argument to key "identifiers" with declared type `set[tuple[str, str]]` on TypedDict `DeviceInfo`: value of type `set[tuple[str, str] | tuple[str, Unknown, Unknown, Unknown]]`
- homeassistant/components/azure_devops/entity.py:23:25: error[invalid-argument-type] Invalid argument to key "identifiers" with declared type `set[tuple[str, str]]` on TypedDict `DeviceInfo`: value of type `set[tuple[str, str, Unknown]]`
+ homeassistant/components/azure_devops/entity.py:23:25: error[invalid-argument-type] Invalid argument to key "identifiers" with declared type `set[tuple[str, str]]` on TypedDict `DeviceInfo`: value of type `set[tuple[str, str] | tuple[str, str, Unknown]]`
- homeassistant/components/hvv_departures/binary_sensor.py:144:25: error[invalid-argument-type] Invalid argument to key "identifiers" with declared type `set[tuple[str, str]]` on TypedDict `DeviceInfo`: value of type `set[tuple[str, Unknown, Unknown, Unknown]]`
+ homeassistant/components/hvv_departures/binary_sensor.py:144:25: error[invalid-argument-type] Invalid argument to key "identifiers" with declared type `set[tuple[str, str]]` on TypedDict `DeviceInfo`: value of type `set[tuple[str, str] | tuple[str, Unknown, Unknown, Unknown]]`
- homeassistant/components/hvv_departures/sensor.py:79:25: error[invalid-argument-type] Invalid argument to key "identifiers" with declared type `set[tuple[str, str]]` on TypedDict `DeviceInfo`: value of type `set[tuple[str, Unknown, Unknown, Unknown]]`
+ homeassistant/components/hvv_departures/sensor.py:79:25: error[invalid-argument-type] Invalid argument to key "identifiers" with declared type `set[tuple[str, str]]` on TypedDict `DeviceInfo`: value of type `set[tuple[str, str] | tuple[str, Unknown, Unknown, Unknown]]`
- homeassistant/components/izone/climate.py:479:25: error[invalid-argument-type] Invalid argument to key "identifiers" with declared type `set[tuple[str, str]]` on TypedDict `DeviceInfo`: value of type `set[tuple[str, str, Unknown]]`
+ homeassistant/components/izone/climate.py:479:25: error[invalid-argument-type] Invalid argument to key "identifiers" with declared type `set[tuple[str, str]]` on TypedDict `DeviceInfo`: value of type `set[tuple[str, str] | tuple[str, str, Unknown]]`
- homeassistant/components/smhi/weather.py:168:28: error[missing-typed-dict-key] Missing required key 'datetime' in TypedDict `Forecast` constructor
- homeassistant/components/toon/entity.py:43:25: error[invalid-argument-type] Invalid argument to key "identifiers" with declared type `set[tuple[str, str]]` on TypedDict `DeviceInfo`: value of type `set[tuple[str, Unknown, str]]`
+ homeassistant/components/toon/entity.py:43:25: error[invalid-argument-type] Invalid argument to key "identifiers" with declared type `set[tuple[str, str]]` on TypedDict `DeviceInfo`: value of type `set[tuple[str, str] | tuple[str, Unknown, str]]`
- homeassistant/components/toon/entity.py:63:25: error[invalid-argument-type] Invalid argument to key "identifiers" with declared type `set[tuple[str, str]]` on TypedDict `DeviceInfo`: value of type `set[tuple[str, Unknown, str]]`
+ homeassistant/components/toon/entity.py:63:25: error[invalid-argument-type] Invalid argument to key "identifiers" with declared type `set[tuple[str, str]]` on TypedDict `DeviceInfo`: value of type `set[tuple[str, str] | tuple[str, Unknown, str]]`
- homeassistant/components/toon/entity.py:83:25: error[invalid-argument-type] Invalid argument to key "identifiers" with declared type `set[tuple[str, str]]` on TypedDict `DeviceInfo`: value of type `set[tuple[str, Unknown, str]]`
+ homeassistant/components/toon/entity.py:83:25: error[invalid-argument-type] Invalid argument to key "identifiers" with declared type `set[tuple[str, str]]` on TypedDict `DeviceInfo`: value of type `set[tuple[str, str] | tuple[str, Unknown, str]]`
- homeassistant/components/toon/entity.py:103:25: error[invalid-argument-type] Invalid argument to key "identifiers" with declared type `set[tuple[str, str]]` on TypedDict `DeviceInfo`: value of type `set[tuple[str, Unknown, str]]`
+ homeassistant/components/toon/entity.py:103:25: error[invalid-argument-type] Invalid argument to key "identifiers" with declared type `set[tuple[str, str]]` on TypedDict `DeviceInfo`: value of type `set[tuple[str, str] | tuple[str, Unknown, str]]`
- homeassistant/components/toon/entity.py:124:25: error[invalid-argument-type] Invalid argument to key "identifiers" with declared type `set[tuple[str, str]]` on TypedDict `DeviceInfo`: value of type `set[tuple[str, Unknown, str]]`
+ homeassistant/components/toon/entity.py:124:25: error[invalid-argument-type] Invalid argument to key "identifiers" with declared type `set[tuple[str, str]]` on TypedDict `DeviceInfo`: value of type `set[tuple[str, str] | tuple[str, Unknown, str]]`
- homeassistant/components/toon/entity.py:144:25: error[invalid-argument-type] Invalid argument to key "identifiers" with declared type `set[tuple[str, str]]` on TypedDict `DeviceInfo`: value of type `set[tuple[str, Unknown, str]]`
+ homeassistant/components/toon/entity.py:144:25: error[invalid-argument-type] Invalid argument to key "identifiers" with declared type `set[tuple[str, str]]` on TypedDict `DeviceInfo`: value of type `set[tuple[str, str] | tuple[str, Unknown, str]]`
- Found 12115 diagnostics
+ Found 12114 diagnostics

@astral-sh-bot
Copy link

astral-sh-bot bot commented Mar 13, 2026

Memory usage report

Summary

Project Old New Diff Outcome
flake8 47.89MB 47.88MB -0.01% (5.91kB) ⬇️
trio 117.75MB 117.72MB -0.02% (28.26kB) ⬇️
sphinx 265.25MB 265.19MB -0.02% (57.58kB) ⬇️
prefect 705.20MB 704.86MB -0.05% (339.73kB) ⬇️

Significant changes

Click to expand detailed breakdown

flake8

Name Old New Diff Outcome
infer_definition_types 1.86MB 1.86MB -0.12% (2.30kB) ⬇️
code_generator_of_static_class 60.14kB 59.00kB -1.88% (1.13kB) ⬇️
infer_scope_types_impl 1002.21kB 1001.13kB -0.11% (1.08kB) ⬇️
infer_expression_types_impl 1.07MB 1.06MB -0.08% (912.00B) ⬇️
code_generator_of_static_class::interned_arguments 29.81kB 29.32kB -1.65% (504.00B) ⬇️
infer_deferred_types 690.22kB 690.20kB -0.00% (24.00B) ⬇️

trio

Name Old New Diff Outcome
infer_scope_types_impl 4.79MB 4.78MB -0.18% (8.77kB) ⬇️
infer_expression_types_impl 7.06MB 7.05MB -0.12% (8.65kB) ⬇️
infer_definition_types 7.57MB 7.56MB -0.10% (7.85kB) ⬇️
infer_expression_type_impl 1.43MB 1.43MB -0.06% (912.00B) ⬇️
code_generator_of_static_class 210.72kB 209.89kB -0.40% (856.00B) ⬇️
code_generator_of_static_class::interned_arguments 104.06kB 103.71kB -0.34% (360.00B) ⬇️
all_narrowing_constraints_for_expression 600.60kB 600.32kB -0.05% (288.00B) ⬇️
loop_header_reachability 133.74kB 133.51kB -0.18% (240.00B) ⬇️
Type<'db>::member_lookup_with_policy_ 1.66MB 1.66MB -0.01% (168.00B) ⬇️
infer_deferred_types 2.37MB 2.37MB -0.00% (96.00B) ⬇️
StaticClassLiteral<'db>::implicit_attribute_inner_ 730.54kB 730.45kB -0.01% (96.00B) ⬇️
all_negative_narrowing_constraints_for_expression 184.73kB 184.69kB -0.03% (48.00B) ⬇️

sphinx

Name Old New Diff Outcome
infer_expression_types_impl 21.52MB 21.49MB -0.10% (22.66kB) ⬇️
infer_definition_types 24.03MB 24.01MB -0.08% (18.96kB) ⬇️
infer_scope_types_impl 15.58MB 15.57MB -0.07% (10.62kB) ⬇️
code_generator_of_static_class 529.25kB 526.47kB -0.53% (2.78kB) ⬇️
code_generator_of_static_class::interned_arguments 264.38kB 263.18kB -0.45% (1.20kB) ⬇️
infer_expression_type_impl 3.21MB 3.21MB -0.02% (648.00B) ⬇️
infer_deferred_types 5.60MB 5.60MB -0.01% (336.00B) ⬇️
Type<'db>::member_lookup_with_policy_ 6.10MB 6.10MB -0.00% (120.00B) ⬇️
StaticClassLiteral<'db>::implicit_attribute_inner_ 2.37MB 2.37MB -0.00% (120.00B) ⬇️
all_narrowing_constraints_for_expression 2.34MB 2.34MB -0.00% (72.00B) ⬇️
all_negative_narrowing_constraints_for_expression 1.01MB 1.01MB -0.00% (48.00B) ⬇️
loop_header_reachability 381.17kB 381.12kB -0.01% (48.00B) ⬇️

prefect

Name Old New Diff Outcome
infer_definition_types 88.89MB 88.75MB -0.16% (146.17kB) ⬇️
infer_expression_types_impl 60.77MB 60.67MB -0.16% (100.76kB) ⬇️
infer_scope_types_impl 52.94MB 52.89MB -0.09% (47.23kB) ⬇️
infer_expression_type_impl 14.34MB 14.33MB -0.11% (15.52kB) ⬇️
UnionType<'db>::from_two_elements_ 5.16MB 5.15MB -0.16% (8.32kB) ⬇️
StaticClassLiteral<'db>::implicit_attribute_inner_ 9.74MB 9.74MB -0.07% (6.85kB) ⬇️
is_redundant_with_impl 5.57MB 5.57MB -0.09% (4.95kB) ⬇️
all_narrowing_constraints_for_expression 7.00MB 7.00MB -0.06% (4.29kB) ⬇️
infer_deferred_types 14.37MB 14.37MB -0.03% (3.89kB) ⬇️
Type<'db>::apply_specialization_::interned_arguments 2.88MB 2.88MB +0.13% (3.75kB) ⬇️
Type<'db>::apply_specialization_ 3.61MB 3.61MB +0.09% (3.48kB) ⬇️
Type<'db>::member_lookup_with_policy_ 15.41MB 15.40MB -0.02% (3.40kB) ⬇️
CallableType 1.89MB 1.89MB +0.17% (3.38kB) ⬇️
is_redundant_with_impl::interned_arguments 5.36MB 5.36MB -0.06% (3.35kB) ⬇️
code_generator_of_static_class 1.80MB 1.80MB -0.16% (2.98kB) ⬇️
... 27 more

@AlexWaygood AlexWaygood changed the title [ty] Synthesize TypedDict constructors via __new__ [ty] Synthesize TypedDict constructors via __new__ Mar 13, 2026
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.

Use type context from synthesized TypedDict constructor when inferring arguments passed to that constructor

1 participant