ruff/crates/ty_python_semantic/src
David Peter 14fbc2b167
[ty] New Type variant for TypedDict (#19733)
## Summary

This PR adds a new `Type::TypedDict` variant. Before this PR, we treated
`TypedDict`-based types as dynamic Todo-types, and I originally planned
to make this change a no-op. And we do in fact still treat that new
variant similar to a dynamic type when it comes to type properties such
as assignability and subtyping. But then I somehow tricked myself into
implementing some of the things correctly, so here we are. The two main
behavioral changes are: (1) we now also detect generic `TypedDict`s,
which removes a few false positives in the ecosystem, and (2) we now
support *attribute* access (not key-based indexing!) on these types,
i.e. we infer proper types for something like
`MyTypedDict.__required_keys__`. Nothing exciting yet, but gets the
infrastructure into place.

Note that with this PR, the type of (the type) `MyTypedDict` itself is
still represented as a `Type::ClassLiteral` or `Type::GenericAlias` (in
case `MyTypedDict` is generic). Only inhabitants of `MyTypedDict`
(instances of `dict` at runtime) are represented by `Type::TypedDict`.
We may want to revisit this decision in the future, if this turns out to
be too error-prone. Right now, we need to use `.is_typed_dict(db)` in
all the right places to distinguish between actual (generic) classes and
`TypedDict`s. But so far, it seemed unnecessary to add additional `Type`
variants for these as well.

part of https://github.com/astral-sh/ty/issues/154

## Ecosystem impact

The new diagnostics on `cloud-init` look like true positives to me.

## Test Plan

Updated and new Markdown tests
2025-08-05 11:19:49 +02:00
..
module_resolver [ty] Remove KnownModule::is_enum (#19681) 2025-08-01 10:31:12 +02:00
semantic_index [ty] fix incorrect lazy scope narrowing (#19744) 2025-08-04 20:32:08 -07:00
types [ty] New Type variant for TypedDict (#19733) 2025-08-05 11:19:49 +02:00
util [ty] Simplify lifetime requirements for PySlice trait (#19687) 2025-08-01 15:13:47 +01:00
ast_node_ref.rs [ty] Add environment variable to dump Salsa memory usage stats (#18928) 2025-06-26 21:27:51 +00:00
db.rs [ty] Track open files in the server (#19264) 2025-07-18 19:33:35 +05:30
dunder_all.rs Simplify get_size2 usage (#19643) 2025-07-30 15:31:37 -04:00
lib.rs [ty] Remove KnownModule::is_enum (#19681) 2025-08-01 10:31:12 +02:00
lint.rs [ty] Add environment variable to dump Salsa memory usage stats (#18928) 2025-06-26 21:27:51 +00:00
list.rs [ty] Add environment variable to dump Salsa memory usage stats (#18928) 2025-06-26 21:27:51 +00:00
module_name.rs [ty] Make Module a Salsa ingredient 2025-07-23 09:46:40 -04:00
node_key.rs [ty] Add environment variable to dump Salsa memory usage stats (#18928) 2025-06-26 21:27:51 +00:00
place.rs [ty] Remove KnownModule::is_enum (#19681) 2025-08-01 10:31:12 +02:00
program.rs [ty] Use python version and path from Python extension (#19012) 2025-07-14 09:47:27 +00:00
pull_types.rs Update Rust toolchain to 1.88 and MSRV to 1.86 (#19011) 2025-06-28 20:24:00 +02:00
python_platform.rs Hug closing } when f-string expression has a format specifier (#18704) 2025-06-17 07:39:42 +02:00
rank.rs [ty] Garbage-collect reachability constraints (#19414) 2025-07-21 14:16:27 -04:00
semantic_index.rs Simplify get_size2 usage (#19643) 2025-07-30 15:31:37 -04:00
semantic_model.rs [ty] New Type variant for TypedDict (#19733) 2025-08-05 11:19:49 +02:00
site_packages.rs [ty] Use python version and path from Python extension (#19012) 2025-07-14 09:47:27 +00:00
suppression.rs Simplify get_size2 usage (#19643) 2025-07-30 15:31:37 -04:00
types.rs [ty] New Type variant for TypedDict (#19733) 2025-08-05 11:19:49 +02:00
unpack.rs [ty] Async for loops and async iterables (#19634) 2025-07-30 17:40:24 +02:00