mirror of
https://github.com/astral-sh/ruff.git
synced 2026-10-28 10:45:37 +08:00
An annotated assignment could lose its declared type in an exception handler, when the path to the exception handler is through an exception evaluating its right-hand side. Assignments in the handler were then inferred without that type context, so a fallback assignment could acquire an incompatible value type, without the benefit of type context from the declared type. This is arguably "expected behavior" in our flow-sensitive declared-types model, but intuitively it feels like the declaration should "take effect" before the RHS "executes". Modeling it that way requires a bit of new machinery in the use-def map to allow splitting the declaration and binding from a single assignment in control flow, but it's not too bad and even allows some simplifications. Record the declaration before visiting the annotation and right-hand side, then record the value binding only after the right-hand side completes. The two control-flow entries retain their execution order, but only the binding participates in usage analysis. Keeping usage state in those entries also removes the parallel usage vector. This preserves ty's existing exception-point model. Fixes astral-sh/ty#4293. ## Test plan - Exception-flow mdtests cover contextual dictionary inference, incompatible fallback assignments, previous or unbound values, reannotations, declarations after an earlier exception checkpoint, and assignments made inside the right-hand side. - Unused-binding tests cover annotated loop-carried values, shadowed annotated bindings, and later bindings captured by closures.
ty_python_core
This crate is an internal component of Ruff. The Rust API exposed here is unstable and will have frequent breaking changes.
This version (0.0.9) is a component of Ruff 0.16.3. The source can be found here.
See Ruff's crate versioning policy for details on versioning.