mirror of
https://github.com/astral-sh/ruff.git
synced 2025-08-04 02:38:25 +00:00
Remove ExprContext
from ComparableExpr
(#7362)
`ComparableExpr` includes the `ExprContext` field on an expression, so, e.g., the two tuples in `(a, b) = (a, b)` won't be considered equal. Similarly, the tuples in `[(a, b) for (a, b) in c]` _also_ wouldn't be considered equal. I find this behavior surprising, since `ComparableExpr` is intended to allow you to compare two ASTs, but `ExprContext` is really encoding information about the broader context for the expression.
This commit is contained in:
parent
34c1cb7d11
commit
ec2f229a45
2 changed files with 38 additions and 48 deletions
|
@ -1,25 +1,23 @@
|
|||
//! An equivalent object hierarchy to the `RustPython` AST hierarchy, but with the
|
||||
//! ability to compare expressions for equality (via [`Eq`] and [`Hash`]).
|
||||
//!
|
||||
//! Two [`ComparableExpr`]s are considered equal if the underlying AST nodes have the
|
||||
//! same shape, ignoring trivia (e.g., parentheses, comments, and whitespace), the
|
||||
//! location in the source code, and other contextual information (e.g., whether they
|
||||
//! represent reads or writes, which is typically encoded in the Python AST).
|
||||
//!
|
||||
//! For example, in `[(a, b) for a, b in c]`, the `(a, b)` and `a, b` expressions are
|
||||
//! considered equal, despite the former being parenthesized, and despite the former
|
||||
//! being a write ([`ast::ExprContext::Store`]) and the latter being a read
|
||||
//! ([`ast::ExprContext::Load`]).
|
||||
//!
|
||||
//! Similarly, `"a" "b"` and `"ab"` would be considered equal, despite the former being
|
||||
//! an implicit concatenation of string literals, as these expressions are considered to
|
||||
//! have the same shape in that they evaluate to the same value.
|
||||
|
||||
use crate as ast;
|
||||
use num_bigint::BigInt;
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Hash, Copy, Clone)]
|
||||
pub enum ComparableExprContext {
|
||||
Load,
|
||||
Store,
|
||||
Del,
|
||||
}
|
||||
|
||||
impl From<&ast::ExprContext> for ComparableExprContext {
|
||||
fn from(ctx: &ast::ExprContext) -> Self {
|
||||
match ctx {
|
||||
ast::ExprContext::Load => Self::Load,
|
||||
ast::ExprContext::Store => Self::Store,
|
||||
ast::ExprContext::Del => Self::Del,
|
||||
}
|
||||
}
|
||||
}
|
||||
use crate as ast;
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Hash, Copy, Clone)]
|
||||
pub enum ComparableBoolOp {
|
||||
|
@ -665,38 +663,32 @@ pub struct ExprConstant<'a> {
|
|||
pub struct ExprAttribute<'a> {
|
||||
value: Box<ComparableExpr<'a>>,
|
||||
attr: &'a str,
|
||||
ctx: ComparableExprContext,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Hash)]
|
||||
pub struct ExprSubscript<'a> {
|
||||
value: Box<ComparableExpr<'a>>,
|
||||
slice: Box<ComparableExpr<'a>>,
|
||||
ctx: ComparableExprContext,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Hash)]
|
||||
pub struct ExprStarred<'a> {
|
||||
value: Box<ComparableExpr<'a>>,
|
||||
ctx: ComparableExprContext,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Hash)]
|
||||
pub struct ExprName<'a> {
|
||||
id: &'a str,
|
||||
ctx: ComparableExprContext,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Hash)]
|
||||
pub struct ExprList<'a> {
|
||||
elts: Vec<ComparableExpr<'a>>,
|
||||
ctx: ComparableExprContext,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Hash)]
|
||||
pub struct ExprTuple<'a> {
|
||||
elts: Vec<ComparableExpr<'a>>,
|
||||
ctx: ComparableExprContext,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Hash)]
|
||||
|
@ -915,50 +907,46 @@ impl<'a> From<&'a ast::Expr> for ComparableExpr<'a> {
|
|||
ast::Expr::Attribute(ast::ExprAttribute {
|
||||
value,
|
||||
attr,
|
||||
ctx,
|
||||
ctx: _,
|
||||
range: _,
|
||||
}) => Self::Attribute(ExprAttribute {
|
||||
value: value.into(),
|
||||
attr: attr.as_str(),
|
||||
ctx: ctx.into(),
|
||||
}),
|
||||
ast::Expr::Subscript(ast::ExprSubscript {
|
||||
value,
|
||||
slice,
|
||||
ctx,
|
||||
ctx: _,
|
||||
range: _,
|
||||
}) => Self::Subscript(ExprSubscript {
|
||||
value: value.into(),
|
||||
slice: slice.into(),
|
||||
ctx: ctx.into(),
|
||||
}),
|
||||
ast::Expr::Starred(ast::ExprStarred {
|
||||
value,
|
||||
ctx,
|
||||
ctx: _,
|
||||
range: _,
|
||||
}) => Self::Starred(ExprStarred {
|
||||
value: value.into(),
|
||||
ctx: ctx.into(),
|
||||
}),
|
||||
ast::Expr::Name(ast::ExprName { id, ctx, range: _ }) => Self::Name(ExprName {
|
||||
id: id.as_str(),
|
||||
ctx: ctx.into(),
|
||||
}),
|
||||
ast::Expr::Name(ast::ExprName {
|
||||
id,
|
||||
ctx: _,
|
||||
range: _,
|
||||
}) => Self::Name(ExprName { id: id.as_str() }),
|
||||
ast::Expr::List(ast::ExprList {
|
||||
elts,
|
||||
ctx,
|
||||
ctx: _,
|
||||
range: _,
|
||||
}) => Self::List(ExprList {
|
||||
elts: elts.iter().map(Into::into).collect(),
|
||||
ctx: ctx.into(),
|
||||
}),
|
||||
ast::Expr::Tuple(ast::ExprTuple {
|
||||
elts,
|
||||
ctx,
|
||||
ctx: _,
|
||||
range: _,
|
||||
}) => Self::Tuple(ExprTuple {
|
||||
elts: elts.iter().map(Into::into).collect(),
|
||||
ctx: ctx.into(),
|
||||
}),
|
||||
ast::Expr::Slice(ast::ExprSlice {
|
||||
lower,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue