Skip to content

Commit

Permalink
Avoid parenthesizing octal/hex or binary literals in object positions (
Browse files Browse the repository at this point in the history
  • Loading branch information
MichaReiser authored Oct 24, 2023
1 parent 84979f9 commit 8b665f4
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 116 deletions.
35 changes: 27 additions & 8 deletions crates/ruff_python_formatter/src/expression/expr_attribute.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,13 @@ impl FormatNodeRule<ExprAttribute> for FormatExprAttribute {

let format_inner = format_with(|f: &mut PyFormatter| {
let parenthesize_value =
// If the value is an integer, we need to parenthesize it to avoid a syntax error.
matches!(
value.as_ref(),
Expr::Constant(ExprConstant {
value: Constant::Int(_) | Constant::Float(_),
..
})
) || is_expression_parenthesized(value.into(), f.context().comments().ranges(), f.context().source());
is_base_ten_number_literal(value.as_ref(), f.context().source()) || {
is_expression_parenthesized(
value.into(),
f.context().comments().ranges(),
f.context().source(),
)
};

if call_chain_layout == CallChainLayout::Fluent {
if parenthesize_value {
Expand Down Expand Up @@ -164,3 +163,23 @@ impl NeedsParentheses for ExprAttribute {
}
}
}

// Non Hex, octal or binary number literals need parentheses to disambiguate the attribute `.` from
// a decimal point. Floating point numbers don't strictly need parentheses but it reads better (rather than 0.0.test()).
fn is_base_ten_number_literal(expr: &Expr, source: &str) -> bool {
if let Some(ExprConstant { value, range }) = expr.as_constant_expr() {
match value {
Constant::Float(_) => true,
Constant::Int(_) => {
let text = &source[*range];
!matches!(
text.as_bytes().get(0..2),
Some([b'0', b'x' | b'X' | b'o' | b'O' | b'b' | b'B'])
)
}
_ => false,
}
} else {
false
}
}

This file was deleted.

0 comments on commit 8b665f4

Please sign in to comment.