Skip to content

Don't add unnecessary parentheses during inline variable extraction#3935

Open
ak4-sh wants to merge 4 commits into
facebook:mainfrom
ak4-sh:inline-paranthesis-fix
Open

Don't add unnecessary parentheses during inline variable extraction#3935
ak4-sh wants to merge 4 commits into
facebook:mainfrom
ak4-sh:inline-paranthesis-fix

Conversation

@ak4-sh

@ak4-sh ak4-sh commented Jun 24, 2026

Copy link
Copy Markdown

Summary

Fix inline variable refactoring to only add parentheses when they are needed for the expression being inlined and the context where it is inserted.

  • Parenthesize expressions that require grouping, such as binary operations, boolean operations, comparisons, tuples, lambdas, and similar expression forms.
  • Avoid unnecessary parentheses for simple values like number literals in normal expression contexts.
  • Add parentheses for number literals when inlining into attribute access, e.g. value = 42; value.bit_length() becomes (42).bit_length().

Fixes #3882

Test Plan

Added LSP code action tests for:

  • Binary expression inlined into attribute access.
  • Number literal inlined without unnecessary parentheses.
  • Number literal inlined into attribute access.
  • Boolean operation requiring parentheses.
  • Tuple expression requiring parentheses.
ak4-sh added 2 commits June 24, 2026 16:36
- Following nodes get parantheses: BinOp, BoolOp, Compare, UnaryOp,
IfExp, Lambda, NamedExpr, GeneratorExp, Tuple, Await, Yield, YieldFrom

- Constant AST nodes get parantheses if they're being inlined into an
attr acces node

Remove debug comments and avoid creating replacement clones

Replacement text is being freshly generated per reference hence clone
not needed

Rename test

Move always_needs_parens out of loop
@meta-cla meta-cla Bot added the cla signed label Jun 24, 2026
@yangdanny97 yangdanny97 changed the title Inline paranthesis fix Jun 26, 2026

@NathanTempest NathanTempest left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the fix, @ak4-sh !

One tiny optional follow-up (not blocking): NumberLiteral also matches floats/complex, but only integer literals have the 42. ambiguity
4.2.foo and 4j.foo are already valid Python, so they'll get a harmless-but-redundant (...). If you want to be minimal you could narrow that check to integer literals, but the current behavior is perfectly safe. Thanks again!

@meta-codesync

meta-codesync Bot commented Jun 29, 2026

Copy link
Copy Markdown
Contributor

@NathanTempest has imported this pull request. If you are a Meta employee, you can view this in D110088158.

@kinto0 kinto0 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review automatically exported from Phabricator review in Meta.

@ndmitchell ndmitchell left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review automatically exported from Phabricator review in Meta.

@github-actions github-actions Bot added size/m and removed size/m labels Jun 29, 2026
@ak4-sh

ak4-sh commented Jun 29, 2026

Copy link
Copy Markdown
Author

Thanks for the comment @NathanTempest! I've updated the match condition, do let me know if it looks okay

@ak4-sh ak4-sh requested a review from NathanTempest June 29, 2026 20:40

@NathanTempest NathanTempest left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good work! The Number::Int narrowing is exactly right, floats/complex no longer get redundant parens while decimal ints (42.bit_length()) are still handled. One small convention nit: we keep imports at the top rather than inline-qualified paths, so use ruff_python_ast::Number; + Number::Int(_) (matches how alt/expr.rs does it). Optionally, a quick negative test that 4.2.foo stays unparenthesized would lock in the new behavior. Thanks for iterating on this!

@github-actions github-actions Bot added size/m and removed size/m labels Jun 29, 2026
@ak4-sh

ak4-sh commented Jun 29, 2026

Copy link
Copy Markdown
Author

@NathanTempest Made the updates, sorry about this!

@ak4-sh ak4-sh requested a review from NathanTempest June 29, 2026 22:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

4 participants