mirror of
https://github.com/astral-sh/ruff.git
synced 2025-09-30 13:51:37 +00:00
[red-knot] Silence unresolved-attribute
in unreachable code (#17305)
## Summary Basically just repeat the same thing that we did for `unresolved-reference`, but now for attribute expressions. We now also handle the case where the unresolved attribute (or the unresolved reference) diagnostic originates from a stringified type annotation. And I made the evaluation of reachability constraints lazy (will only be evaluated right before we are about to emit a diagnostic). ## Test Plan New Markdown tests for stringified annotations.
This commit is contained in:
parent
ec74f2d522
commit
5b6e94981d
5 changed files with 191 additions and 92 deletions
|
@ -8,7 +8,7 @@ use ruff_db::parsed::ParsedModule;
|
|||
use ruff_index::IndexVec;
|
||||
use ruff_python_ast::name::Name;
|
||||
use ruff_python_ast::visitor::{walk_expr, walk_pattern, walk_stmt, Visitor};
|
||||
use ruff_python_ast::{self as ast, ExprContext};
|
||||
use ruff_python_ast::{self as ast};
|
||||
|
||||
use crate::ast_node_ref::AstNodeRef;
|
||||
use crate::module_name::ModuleName;
|
||||
|
@ -1770,7 +1770,8 @@ where
|
|||
if is_use {
|
||||
self.mark_symbol_used(symbol);
|
||||
let use_id = self.current_ast_ids().record_use(expr);
|
||||
self.current_use_def_map_mut().record_use(symbol, use_id);
|
||||
self.current_use_def_map_mut()
|
||||
.record_use(symbol, use_id, expression_id);
|
||||
}
|
||||
|
||||
if is_definition {
|
||||
|
@ -2011,24 +2012,39 @@ where
|
|||
ast::Expr::Attribute(ast::ExprAttribute {
|
||||
value: object,
|
||||
attr,
|
||||
ctx: ExprContext::Store,
|
||||
ctx,
|
||||
range: _,
|
||||
}) => {
|
||||
if let Some(unpack) = self
|
||||
.current_assignment()
|
||||
.as_ref()
|
||||
.and_then(CurrentAssignment::unpack)
|
||||
{
|
||||
self.register_attribute_assignment(
|
||||
object,
|
||||
attr,
|
||||
AttributeAssignment::Unpack {
|
||||
attribute_expression_id: expression_id,
|
||||
unpack,
|
||||
},
|
||||
);
|
||||
if ctx.is_store() {
|
||||
if let Some(unpack) = self
|
||||
.current_assignment()
|
||||
.as_ref()
|
||||
.and_then(CurrentAssignment::unpack)
|
||||
{
|
||||
self.register_attribute_assignment(
|
||||
object,
|
||||
attr,
|
||||
AttributeAssignment::Unpack {
|
||||
attribute_expression_id: expression_id,
|
||||
unpack,
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Track reachability of attribute expressions to silence `unresolved-attribute`
|
||||
// diagnostics in unreachable code.
|
||||
self.current_use_def_map_mut()
|
||||
.record_expression_reachability(expression_id);
|
||||
|
||||
walk_expr(self, expr);
|
||||
}
|
||||
ast::Expr::StringLiteral(_) => {
|
||||
// Track reachability of string literals, as they could be a stringified annotation
|
||||
// with child expressions whose reachability we are interested in.
|
||||
self.current_use_def_map_mut()
|
||||
.record_expression_reachability(expression_id);
|
||||
|
||||
walk_expr(self, expr);
|
||||
}
|
||||
_ => {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue