Thanks to visit codestin.com
Credit goes to github.com

Skip to content

[ty] Distinguish typing.TypedDict from typing_extensions.TypedDict#25843

Merged
charliermarsh merged 9 commits into
mainfrom
charlie/typing-vs-typing-extensions-typeddict
Jun 25, 2026
Merged

[ty] Distinguish typing.TypedDict from typing_extensions.TypedDict#25843
charliermarsh merged 9 commits into
mainfrom
charlie/typing-vs-typing-extensions-typeddict

Conversation

@charliermarsh

@charliermarsh charliermarsh commented Jun 10, 2026

Copy link
Copy Markdown
Member

Summary

This follows up on #25833. On Python 3.12, classes defined using typing_extensions.TypedDict have runtime attributes that classes defined using typing.TypedDict do not, but we currently treat both definitions as the same special form.

This keeps track of which TypedDict definition was used for class-based, functional, inherited, generic, and dynamically created TypedDicts. Member lookup still uses the shared typeshed declarations first, then consults typing_extensions._TypedDict only for TypedDicts defined using typing_extensions.TypedDict. Their MRO and type relationships remain unchanged.

The regression tests cover typing.TypedDict versus typing_extensions.TypedDict on Python 3.12, verify that typing.TypedDict.__closed__ is unavailable on Python 3.13, and cover the standard-library attributes available on Python 3.15.

@astral-sh-bot astral-sh-bot Bot added the ty Multi-file analysis & type inference label Jun 10, 2026
@astral-sh-bot

astral-sh-bot Bot commented Jun 10, 2026

Copy link
Copy Markdown

Memory usage report

Summary

Project Old New Diff Outcome
prefect 450.62MB 450.63MB +0.00% (13.95kB)
sphinx 167.31MB 167.31MB +0.00% (888.00B)
trio 70.61MB 70.61MB +0.00% (520.00B)
flake8 29.15MB 29.15MB -

Significant changes

Click to expand detailed breakdown

prefect

Name Old New Diff Outcome
Type<'db>::class_member_with_policy_ 7.89MB 7.90MB +0.12% (9.59kB)
StaticClassLiteral<'db>::typed_dict_module_ 0.00B 2.16kB +2.16kB (new)
infer_definition_types 50.56MB 50.56MB +0.00% (628.00B)
infer_deferred_types 6.08MB 6.08MB +0.01% (324.00B)
StaticClassLiteral<'db>::try_mro_ 3.35MB 3.35MB +0.01% (240.00B)
try_metaclass_inner 565.11kB 565.27kB +0.03% (168.00B)
StaticClassLiteral 835.17kB 835.29kB +0.01% (128.00B)
explicit_bases_inner 370.12kB 370.21kB +0.03% (96.00B)
code_generator_of_static_class 399.09kB 399.18kB +0.02% (96.00B)
place_by_id 4.86MB 4.86MB +0.00% (88.00B)
inheritance_cycle_inner 198.78kB 198.86kB +0.04% (80.00B)
place_by_id::interned_arguments 3.67MB 3.68MB +0.00% (72.00B)
StaticClassLiteral<'db>::try_mro_::interned_arguments 1.19MB 1.19MB +0.01% (72.00B)
inherited_legacy_generic_context_inner 252.70kB 252.76kB +0.02% (64.00B)
instance_flags_inner 277.59kB 277.66kB +0.02% (64.00B)
... 3 more

sphinx

Name Old New Diff Outcome
StaticClassLiteral<'db>::typed_dict_module_ 0.00B 576.00B +576.00B (new)
Type<'db>::class_member_with_policy_ 3.58MB 3.58MB +0.01% (312.00B)

trio

Name Old New Diff Outcome
StaticClassLiteral<'db>::typed_dict_module_ 0.00B 288.00B +288.00B (new)
Type<'db>::class_member_with_policy_ 888.62kB 888.85kB +0.03% (232.00B)

@astral-sh-bot

astral-sh-bot Bot commented Jun 10, 2026

Copy link
Copy Markdown

Typing conformance results

No changes detected ✅

Current numbers
The percentage of diagnostics emitted that were expected errors held steady at 94.47%. The percentage of expected errors that received a diagnostic held steady at 89.19%. The number of fully passing files held steady at 95/134.

@astral-sh-bot

astral-sh-bot Bot commented Jun 10, 2026

Copy link
Copy Markdown

ecosystem-analyzer results

No diagnostic changes detected ✅

Flaky changes detected. This PR summary excludes flaky changes; see the HTML report for details.

Full report with detailed diff (timing results)

@charliermarsh charliermarsh force-pushed the charlie/typing-vs-typing-extensions-typeddict branch 3 times, most recently from af703c8 to 899bf77 Compare June 10, 2026 21:35
@charliermarsh charliermarsh changed the title [ty] Distinguish typing.TypedDict from typing_extensions.TypedDict [ty] Distinguish typing.TypedDict from typing_extensions.TypedDict Jun 10, 2026
@charliermarsh charliermarsh marked this pull request as ready for review June 10, 2026 23:42
@charliermarsh charliermarsh force-pushed the charlie/typing-vs-typing-extensions-typeddict branch from 0749bca to 2da3cf2 Compare June 12, 2026 16:59
@charliermarsh charliermarsh force-pushed the charlie/typing-vs-typing-extensions-typeddict branch from 2da3cf2 to 0e44f47 Compare June 25, 2026 00:26
@charliermarsh charliermarsh requested review from a team as code owners June 25, 2026 00:26
@charliermarsh charliermarsh merged commit da54334 into main Jun 25, 2026
63 checks passed
@charliermarsh charliermarsh deleted the charlie/typing-vs-typing-extensions-typeddict branch June 25, 2026 01:05
Comment on lines +296 to +301
(Self::TypedDict(_), "TypedDict", KnownModule::Typing) => {
Self::TypedDict(TypedDictModule::Typing)
}
(Self::TypedDict(_), "TypedDict", KnownModule::TypingExtensions) => {
Self::TypedDict(TypedDictModule::TypingExtensions)
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

hmm, it feels quite unfortunate that we have to do this. It seems much less necessary for typeshed to pretend that typing_extension.TypedDict is the same as typing.TypedDict than it does for it to pretend that typing.Callable is the same as collections.abc.Callable. I've opened python/typeshed#15943 to see if we can improve the typeshed definitions here, which would allow us to get rid of this

AlexWaygood added a commit that referenced this pull request Jun 27, 2026
…and `typing_extensions.TypedDict` (#26435)

## Summary

- `typing.TypedDict` and `typing_extensions.TypedDict` are (accurately)
represented as two distinct symbols in the latest version of our
vendored typeshed stubs, so we can get rid of the use of
`rewrap_from_module` (which feels like a _bit_ of a hack, best avoided
where possible) and instead register them as distinct special forms in
the way we usually would. The only snag here is that the two special
forms have the same name, so `SpecialFormType::from_name()` has to be
refactored to return `&'static [Self]` instead of `Option<Self>`, and is
renamed to `SpecialFormType::candidates_from_name` (the name "TypedDict"
has two candidates: `typing.TypedDict` and
`typing_extensions.TypedDict`).
- Add `typing_extensions._TypedDict` as a `KnownClass`. This
significantly simplifies `typed_dict_fallback_class_member` in
`typed_dict.rs`.
- Get rid of `TypedDictModule::Either`. We always treated it exactly the
same as `TypedDictModule::Typing`.

This is a followup to #25843
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