mirror of
https://github.com/astral-sh/ruff.git
synced 2025-08-09 21:28:21 +00:00
Extend nested union detection to handle bitwise or Union
expressions (#6399)
## Summary We have some logic in the expression analyzer method to avoid re-checking the inner `Union` in `Union[Union[...]]`, since the methods that analyze `Union` expressions already recurse. Elsewhere, we have logic to avoid re-checking the inner `|` in `int | (int | str)`, for the same reason. This PR unifies that logic into a single method _and_ ensures that, just as we recurse over both `Union` and `|`, we also detect that we're in _either_ kind of nested union. Closes https://github.com/astral-sh/ruff/issues/6285. ## Test Plan Added some new snapshots.
This commit is contained in:
parent
98d4657961
commit
26098b8d91
6 changed files with 627 additions and 167 deletions
|
@ -6,7 +6,7 @@ use smallvec::smallvec;
|
|||
|
||||
use ruff_python_ast::call_path::{collect_call_path, from_unqualified_name, CallPath};
|
||||
use ruff_python_ast::helpers::from_relative_import;
|
||||
use ruff_python_ast::{self as ast, Expr, Ranged, Stmt};
|
||||
use ruff_python_ast::{self as ast, Expr, Operator, Ranged, Stmt};
|
||||
use ruff_python_stdlib::path::is_python_stub_file;
|
||||
use ruff_python_stdlib::typing::is_typing_extension;
|
||||
use ruff_text_size::{TextRange, TextSize};
|
||||
|
@ -1022,6 +1022,34 @@ impl<'a> SemanticModel<'a> {
|
|||
false
|
||||
}
|
||||
|
||||
/// Return `true` if the model is in a nested union expression (e.g., the inner `Union` in
|
||||
/// `Union[Union[int, str], float]`).
|
||||
pub fn in_nested_union(&self) -> bool {
|
||||
// Ex) `Union[Union[int, str], float]`
|
||||
if self
|
||||
.current_expression_grandparent()
|
||||
.and_then(Expr::as_subscript_expr)
|
||||
.is_some_and(|parent| self.match_typing_expr(&parent.value, "Union"))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// Ex) `int | Union[str, float]`
|
||||
if self.current_expression_parent().is_some_and(|parent| {
|
||||
matches!(
|
||||
parent,
|
||||
Expr::BinOp(ast::ExprBinOp {
|
||||
op: Operator::BitOr,
|
||||
..
|
||||
})
|
||||
)
|
||||
}) {
|
||||
return true;
|
||||
}
|
||||
|
||||
false
|
||||
}
|
||||
|
||||
/// Returns `true` if the given [`BindingId`] is used.
|
||||
pub fn is_used(&self, binding_id: BindingId) -> bool {
|
||||
self.bindings[binding_id].is_used()
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue