[red-knot] - Flow-control for boolean operations (#13940)

## Summary

As python uses short-circuiting boolean operations in runtime, we should
mimic that logic in redknot as well.
For example, we should detect that in the following code `x` might be
undefined inside the block:

```py
if flag or (x := 1):
    print(x) 
```

## Test Plan

Added mdtest suit for boolean expressions.

---------

Co-authored-by: Carl Meyer <carl@astral.sh>
This commit is contained in:
TomerBin 2024-10-27 05:33:01 +02:00 committed by GitHub
parent b6ffa51c16
commit 66c3aaa307
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 125 additions and 1 deletions

View file

@ -1106,6 +1106,27 @@ where
},
);
}
ast::Expr::BoolOp(ast::ExprBoolOp {
values,
range: _,
op: _,
}) => {
// TODO detect statically known truthy or falsy values (via type inference, not naive
// AST inspection, so we can't simplify here, need to record test expression for
// later checking)
let mut snapshots = vec![];
for (index, value) in values.iter().enumerate() {
// The first item of BoolOp is always evaluated
if index > 0 {
snapshots.push(self.flow_snapshot());
}
self.visit_expr(value);
}
for snapshot in snapshots {
self.flow_merge(snapshot);
}
}
_ => {
walk_expr(self, expr);
}