-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix instability with await fluent style #8676
Conversation
async def main(): | ||
- await asyncio.sleep(1) # Hello | ||
+ await ( | ||
+ asyncio.sleep(1) # Hello | ||
+ ) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is arguably correct for ruff
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems like really weird formatting. Why is this correct?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note that we don't expand, we just keep
async def main():
await asyncio.sleep(1) # Hello
await (
asyncio.sleep(1) # Hello
)
as-is
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay that's good to know. I guess that's okay. A little weird but fits with previous choices?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why does this work with IfBreaks
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In yield we use Parenthesize::Optional
...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tried that too for that same reason, but it introduced new black deviations:
# Remove brackets for short coroutine/task
async def main():
- await asyncio.sleep(1)
+ await (asyncio.sleep(1))
async def main():
- await asyncio.sleep(1)
+ await (asyncio.sleep(1))
async def main():
- await asyncio.sleep(1)
+ await (asyncio.sleep(1))
|
@@ -20,7 +20,7 @@ impl FormatNodeRule<ExprAwait> for FormatExprAwait { | |||
[ | |||
token("await"), | |||
space(), | |||
maybe_parenthesize_expression(value, item, Parenthesize::IfRequired) | |||
maybe_parenthesize_expression(value, item, Parenthesize::IfBreaks) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this be IfBreaksOrIfRequired
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That one would regress asyncio.gather
# Long lines
async def main():
- await asyncio.gather(
- asyncio.sleep(1),
- asyncio.sleep(1),
- asyncio.sleep(1),
- asyncio.sleep(1),
- asyncio.sleep(1),
- asyncio.sleep(1),
- asyncio.sleep(1),
+ await (
+ asyncio.gather(
+ asyncio.sleep(1),
+ asyncio.sleep(1),
+ asyncio.sleep(1),
+ asyncio.sleep(1),
+ asyncio.sleep(1),
+ asyncio.sleep(1),
+ asyncio.sleep(1),
+ )
)
(i'm happy too implement a different solution btw, this was just the solution that i found to work best by trial and error)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ahh yeah, I agree that that's worse. I feel like I need to have a better understanding of why these Parenthesize
values are leading to these changes before I'd be comfortable approving. Why does IfBreaks
break that way? Will using IfBreaks
ever lead to syntax errors?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, that's handled by OptionalParentheses::Multiline
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll make some better examples why we get this behavior
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you, I'm trying to make sure I play Micha and really understand the impact of formatting changes before approving.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
From the perspective of the await, it needs OptionalParentheses::Never
because the child is already parenthesized, and we're preferring those parentheses over adding them around the await. For the await's child, we have four options:
- Optional: Add parentheses if the child breaks, which we want e.g. for
asyncio.gather
. Keeps the child's parentheses from the source code, which we want to remove. - IfBreaks: Add parentheses if the child breaks, which we want e.g. for
asyncio.gather
. Discards child parentheses, which we want. - IfRequired: Discards child parentheses, which we want. Also discards them when the child breaks but has its own inner parentheses, which would lead to e.g.
, which don't want.
await asyncio.gather( fut1, fut2, )
- IfBreaksOrIfRequired: Special case for return type annotations.
I added comments to the parentheses types to make them better understandable in the future
Fix an instability where await was followed by a breaking fluent style expression:
Note that this technically a minor style change (see ecosystem check)