Preserve dangling f-string comments
<!--
Thank you for contributing to Ruff! To help us out with reviewing, please consider the following:
- Does this pull request include a summary of the change? (See below.)
- Does this pull request include a descriptive title?
- Does this pull request include references to any relevant issues?
-->
## Summary
This PR fixes the issue where the FString formatting dropped dangling comments between the string parts.
```python
result_f = (
f' File "{__file__}", line {lineno_f+1}, in f\n'
' f()\n'
# XXX: The following line changes depending on whether the tests
# are run through the interactive interpreter or with -m
# It also varies depending on the platform (stack size)
# Fortunately, we don't care about exactness here, so we use regex
r' \[Previous line repeated (\d+) more times\]' '\n'
'RecursionError: maximum recursion depth exceeded\n'
)
```
The solution here isn't ideal because it re-introduces the `enclosing_parent` on `DecoratedComment` but it is the easiest fix that I could come up.
I didn't spend more time finding another solution becaues I think we have to re-write most of the fstring formatting with the upcoming Python 3.12 support (because lexing the individual parts as we do now will no longer work).
closes #6440
<!-- What's the purpose of the change? What does it do, and why? -->
## Test Plan
`cargo test`
The child PR testing that all comments are formatted should now pass
This commit is contained in:
@@ -73,6 +73,13 @@ pub(super) fn place_comment<'a>(
|
||||
handle_leading_class_with_decorators_comment(comment, class_def)
|
||||
}
|
||||
AnyNodeRef::StmtImportFrom(import_from) => handle_import_from_comment(comment, import_from),
|
||||
AnyNodeRef::ExprConstant(_) => {
|
||||
if let Some(AnyNodeRef::ExprFString(fstring)) = comment.enclosing_parent() {
|
||||
CommentPlacement::dangling(fstring, comment)
|
||||
} else {
|
||||
CommentPlacement::Default(comment)
|
||||
}
|
||||
}
|
||||
AnyNodeRef::ExprList(_)
|
||||
| AnyNodeRef::ExprSet(_)
|
||||
| AnyNodeRef::ExprGeneratorExp(_)
|
||||
|
||||
@@ -77,6 +77,7 @@ impl<'ast> PreorderVisitor<'ast> for CommentsVisitor<'ast> {
|
||||
enclosing: enclosing_node,
|
||||
preceding: self.preceding_node,
|
||||
following: Some(node),
|
||||
parent: self.parents.iter().rev().nth(1).copied(),
|
||||
line_position: text_position(*comment_range, self.source_code),
|
||||
slice: self.source_code.slice(*comment_range),
|
||||
};
|
||||
@@ -117,6 +118,7 @@ impl<'ast> PreorderVisitor<'ast> for CommentsVisitor<'ast> {
|
||||
|
||||
let comment = DecoratedComment {
|
||||
enclosing: node,
|
||||
parent: self.parents.last().copied(),
|
||||
preceding: self.preceding_node,
|
||||
following: None,
|
||||
line_position: text_position(*comment_range, self.source_code),
|
||||
@@ -179,6 +181,7 @@ pub(super) struct DecoratedComment<'a> {
|
||||
enclosing: AnyNodeRef<'a>,
|
||||
preceding: Option<AnyNodeRef<'a>>,
|
||||
following: Option<AnyNodeRef<'a>>,
|
||||
parent: Option<AnyNodeRef<'a>>,
|
||||
line_position: CommentLinePosition,
|
||||
slice: SourceCodeSlice,
|
||||
}
|
||||
@@ -204,6 +207,11 @@ impl<'a> DecoratedComment<'a> {
|
||||
self.enclosing
|
||||
}
|
||||
|
||||
/// Returns the parent of the enclosing node, if any
|
||||
pub(super) fn enclosing_parent(&self) -> Option<AnyNodeRef<'a>> {
|
||||
self.parent
|
||||
}
|
||||
|
||||
/// Returns the slice into the source code.
|
||||
pub(super) fn slice(&self) -> &SourceCodeSlice {
|
||||
&self.slice
|
||||
|
||||
Reference in New Issue
Block a user