mirror of
https://github.com/astral-sh/ruff.git
synced 2025-08-16 16:40:19 +00:00
Restore existing bindings when unbinding caught exceptions (#5256)
## Summary In the latest release, we made some improvements to the semantic model, but our modifications to exception-unbinding are causing some false-positives. For example: ```py try: v = 3 except ImportError as v: print(v) else: print(v) ``` In the latest release, we started unbinding `v` after the `except` handler. (We used to restore the existing binding, the `v = 3`, but this was quite complicated.) Because we don't have full branch analysis, we can't then know that `v` is still bound in the `else` branch. The solution here modifies `resolve_read` to skip-lookup when hitting unbound exceptions. So when store the "unbind" for `except ImportError as v`, we save the binding that it shadowed `v = 3`, and skip to that. Closes #5249. Closes #5250.
This commit is contained in:
parent
d99b3bf661
commit
ecf61d49fa
13 changed files with 429 additions and 25 deletions
|
@ -75,7 +75,7 @@ impl<'a> Binding<'a> {
|
|||
pub const fn is_unbound(&self) -> bool {
|
||||
matches!(
|
||||
self.kind,
|
||||
BindingKind::Annotation | BindingKind::Deletion | BindingKind::UnboundException
|
||||
BindingKind::Annotation | BindingKind::Deletion | BindingKind::UnboundException(_)
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -427,7 +427,11 @@ pub enum BindingKind<'a> {
|
|||
///
|
||||
/// After the `except` block, `x` is unbound, despite the lack
|
||||
/// of an explicit `del` statement.
|
||||
UnboundException,
|
||||
///
|
||||
///
|
||||
/// Stores the ID of the binding that was shadowed in the enclosing
|
||||
/// scope, if any.
|
||||
UnboundException(Option<BindingId>),
|
||||
}
|
||||
|
||||
bitflags! {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue