Files
ruff/fuzz/Cargo.toml
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

81 lines
2.0 KiB
TOML

[package]
name = "ruff-fuzz"
version = "0.0.0"
authors = [
"Charlie Marsh <charlie.r.marsh@gmail.com>",
"Addison Crump <research@addisoncrump.info>",
]
publish = false
edition = "2021"
[features]
default = ["libfuzzer"]
full-idempotency = []
libfuzzer = ["libfuzzer-sys/link_libfuzzer"]
[package.metadata]
cargo-fuzz = true
[dependencies]
ruff_db = { path = "../crates/ruff_db" }
ruff_linter = { path = "../crates/ruff_linter" }
ruff_python_ast = { path = "../crates/ruff_python_ast" }
ruff_python_codegen = { path = "../crates/ruff_python_codegen" }
ruff_python_parser = { path = "../crates/ruff_python_parser" }
ruff_source_file = { path = "../crates/ruff_source_file" }
ruff_python_formatter = { path = "../crates/ruff_python_formatter" }
ruff_text_size = { path = "../crates/ruff_text_size" }
ty_python_semantic = { path = "../crates/ty_python_semantic" }
ty_vendored = { path = "../crates/ty_vendored" }
libfuzzer-sys = { git = "https://github.com/rust-fuzz/libfuzzer", default-features = false }
salsa = { git = "https://github.com/salsa-rs/salsa.git", rev = "d66fe331d546216132ace503512b94d5c68d2c50", default-features = false, features = [
"compact_str",
"macros",
"salsa_unstable",
"inventory",
] }
similar = { version = "2.5.0" }
tracing = { version = "0.1.40" }
# Prevent this from interfering with workspaces
[workspace]
members = ["."]
[[bin]]
name = "ty_check_invalid_syntax"
path = "fuzz_targets/ty_check_invalid_syntax.rs"
[[bin]]
name = "ruff_parse_simple"
path = "fuzz_targets/ruff_parse_simple.rs"
[[bin]]
name = "ruff_fix_validity"
path = "fuzz_targets/ruff_fix_validity.rs"
[[bin]]
name = "ruff_formatter_validity"
path = "fuzz_targets/ruff_formatter_validity.rs"
[[bin]]
name = "ruff_parse_idempotency"
path = "fuzz_targets/ruff_parse_idempotency.rs"
[[bin]]
name = "ruff_formatter_idempotency"
path = "fuzz_targets/ruff_formatter_idempotency.rs"
[profile.release]
opt-level = 3
debug = true
[profile.dev]
opt-level = 3
debug = true
[profile.test]
opt-level = 3
debug = true