Skip to content

[ty] Stricter validation of TypedDict definitions#22811

Merged
AlexWaygood merged 1 commit intomainfrom
alex/td-keywords
Jan 22, 2026
Merged

[ty] Stricter validation of TypedDict definitions#22811
AlexWaygood merged 1 commit intomainfrom
alex/td-keywords

Conversation

@AlexWaygood
Copy link
Member

Summary

Validate that:

  • TypedDict classes can only extend other TypedDict classes
  • total and closed can only be passed literal bools
  • Unexpected keyword arguments cannot be passed to TypedDict classes
  • Specifying a custom metaclass for a TypedDict is not allowed

While writing this, I realised that we're quite lacking in our keyword validation for regular classes that have custom metaclasses. I tried to fix that too at first, but it quickly spiralled and I realised that TypedDict validation all needs to be special-cased anyway. So here's a standalone TypedDict-validation PR.

Test Plan

mdtests 'n' snapshots

@AlexWaygood AlexWaygood added the ty Multi-file analysis & type inference label Jan 22, 2026
@astral-sh-bot
Copy link

astral-sh-bot bot commented Jan 22, 2026

Typing conformance results improved 🎉

The percentage of diagnostics emitted that were expected errors increased from 77.59% to 77.66%. The percentage of expected errors that received a diagnostic increased from 60.76% to 61.03%.

Summary

Metric Old New Diff Outcome
True Positives 675 678 +3 ⏫ (✅)
False Positives 195 195 +0
False Negatives 436 433 -3 ⏬ (✅)
Total Diagnostics 870 873 +3
Precision 77.59% 77.66% +0.08% ⏫ (✅)
Recall 60.76% 61.03% +0.27% ⏫ (✅)

True positives added

Details
Location Name Message
typeddicts_class_syntax.py:44:32 invalid-typed-dict-header Custom metaclasses are not supported in TypedDict definitions
typeddicts_class_syntax.py:49:32 unknown-argument Unknown keyword argument other in TypedDict definition
typeddicts_inheritance.py:44:31 invalid-typed-dict-header TypedDict class BadTypedDict can only inherit from TypedDict classes: NonTypedDict is not a TypedDict class

@astral-sh-bot
Copy link

astral-sh-bot bot commented Jan 22, 2026

mypy_primer results

Changes were detected when running on open source projects
prefect (https://github.com/PrefectHQ/prefect)
- src/integrations/prefect-dbt/prefect_dbt/core/settings.py:94:28: error[invalid-assignment] Object of type `dict[str, Any] | int | T@resolve_block_document_references | ... omitted 4 union elements` is not assignable to `dict[str, Any]`
+ src/integrations/prefect-dbt/prefect_dbt/core/settings.py:94:28: error[invalid-assignment] Object of type `T@resolve_block_document_references | dict[str, Any]` is not assignable to `dict[str, Any]`
- src/integrations/prefect-dbt/prefect_dbt/core/settings.py:99:28: error[invalid-assignment] Object of type `int | T@resolve_variables | float | ... omitted 4 union elements` is not assignable to `dict[str, Any]`
+ src/integrations/prefect-dbt/prefect_dbt/core/settings.py:99:28: error[invalid-assignment] Object of type `T@resolve_variables | dict[str, Any]` is not assignable to `dict[str, Any]`
- src/prefect/cli/deploy/_core.py:86:21: error[invalid-assignment] Object of type `dict[str, Any] | int | T@resolve_block_document_references | ... omitted 4 union elements` is not assignable to `dict[str, Any]`
+ src/prefect/cli/deploy/_core.py:86:21: error[invalid-assignment] Object of type `T@resolve_block_document_references | dict[str, Any]` is not assignable to `dict[str, Any]`
- src/prefect/cli/deploy/_core.py:87:21: error[invalid-assignment] Object of type `int | T@resolve_variables | float | ... omitted 4 union elements` is not assignable to `dict[str, Any]`
+ src/prefect/cli/deploy/_core.py:87:21: error[invalid-assignment] Object of type `T@resolve_variables` is not assignable to `dict[str, Any]`
- src/prefect/deployments/steps/core.py:137:38: error[invalid-argument-type] Argument is incorrect: Expected `T@resolve_variables`, found `dict[str, Any] | int | T@resolve_block_document_references | ... omitted 4 union elements`
+ src/prefect/deployments/steps/core.py:137:38: error[invalid-argument-type] Argument is incorrect: Expected `T@resolve_variables`, found `T@resolve_block_document_references | dict[str, Any]`
- src/prefect/utilities/templating.py:320:13: error[invalid-assignment] Invalid subscript assignment with key of type `object` and value of type `dict[str, Any] | int | T@resolve_block_document_references | ... omitted 4 union elements` on object of type `dict[str, Any]`
+ src/prefect/utilities/templating.py:320:13: error[invalid-assignment] Invalid subscript assignment with key of type `object` and value of type `T@resolve_block_document_references | dict[str, Any]` on object of type `dict[str, Any]`
- src/prefect/utilities/templating.py:323:16: error[invalid-return-type] Return type does not match returned value: expected `T@resolve_block_document_references | dict[str, Any]`, found `list[Unknown | dict[str, Any] | int | ... omitted 5 union elements]`
+ src/prefect/utilities/templating.py:323:16: error[invalid-return-type] Return type does not match returned value: expected `T@resolve_block_document_references | dict[str, Any]`, found `list[Unknown | T@resolve_block_document_references | dict[str, Any]]`
- src/prefect/utilities/templating.py:437:16: error[invalid-return-type] Return type does not match returned value: expected `T@resolve_variables`, found `dict[object, Unknown | int | T@resolve_variables | ... omitted 5 union elements]`
+ src/prefect/utilities/templating.py:437:16: error[invalid-return-type] Return type does not match returned value: expected `T@resolve_variables`, found `dict[object, Unknown | T@resolve_variables]`
- src/prefect/utilities/templating.py:442:16: error[invalid-return-type] Return type does not match returned value: expected `T@resolve_variables`, found `list[Unknown | int | T@resolve_variables | ... omitted 5 union elements]`
+ src/prefect/utilities/templating.py:442:16: error[invalid-return-type] Return type does not match returned value: expected `T@resolve_variables`, found `list[Unknown | T@resolve_variables]`
- src/prefect/workers/base.py:232:13: error[invalid-argument-type] Argument is incorrect: Expected `T@resolve_variables`, found `dict[str, Any] | int | T@resolve_block_document_references | ... omitted 4 union elements`
+ src/prefect/workers/base.py:232:13: error[invalid-argument-type] Argument is incorrect: Expected `T@resolve_variables`, found `T@resolve_block_document_references | dict[str, Any]`
- src/prefect/workers/base.py:234:20: error[invalid-argument-type] Argument expression after ** must be a mapping type: Found `int | T@resolve_variables | float | ... omitted 4 union elements`
+ src/prefect/workers/base.py:234:20: error[invalid-argument-type] Argument expression after ** must be a mapping type: Found `T@resolve_variables`

scikit-build-core (https://github.com/scikit-build/scikit-build-core)
+ src/scikit_build_core/build/wheel.py:99:20: error[no-matching-overload] No overload of bound method `__init__` matches arguments
- Found 46 diagnostics
+ Found 47 diagnostics

No memory usage changes detected ✅

@AlexWaygood AlexWaygood marked this pull request as ready for review January 22, 2026 20:05
@AlexWaygood AlexWaygood enabled auto-merge (squash) January 22, 2026 20:50
@AlexWaygood AlexWaygood merged commit f4b84a9 into main Jan 22, 2026
44 checks passed
@AlexWaygood AlexWaygood deleted the alex/td-keywords branch January 22, 2026 21:09
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.

2 participants