mirror of
https://github.com/astral-sh/ruff.git
synced 2025-08-10 05:38:15 +00:00
Disallow newlines in format specifiers of single quoted f- or t-strings (#18708)
This commit is contained in:
parent
23261a38a0
commit
1188ffccc4
17 changed files with 521 additions and 513 deletions
|
@ -323,27 +323,18 @@ fn handle_enclosed_comment<'a>(
|
|||
AnyNodeRef::TString(tstring) => CommentPlacement::dangling(tstring, comment),
|
||||
AnyNodeRef::InterpolatedElement(element) => {
|
||||
if let Some(preceding) = comment.preceding_node() {
|
||||
if comment.line_position().is_own_line() && element.format_spec.is_some() {
|
||||
return if comment.following_node().is_some() {
|
||||
// Own line comment before format specifier
|
||||
// ```py
|
||||
// aaaaaaaaaaa = f"""asaaaaaaaaaaaaaaaa {
|
||||
// aaaaaaaaaaaa + bbbbbbbbbbbb + ccccccccccccccc + dddddddd
|
||||
// # comment
|
||||
// :.3f} cccccccccc"""
|
||||
// ```
|
||||
CommentPlacement::trailing(preceding, comment)
|
||||
} else {
|
||||
// TODO: This can be removed once format specifiers with a newline are a syntax error.
|
||||
// This is to handle cases like:
|
||||
// ```py
|
||||
// x = f"{x !s
|
||||
// :>0
|
||||
// # comment 21
|
||||
// }"
|
||||
// ```
|
||||
CommentPlacement::trailing(element, comment)
|
||||
};
|
||||
// Own line comment before format specifier
|
||||
// ```py
|
||||
// aaaaaaaaaaa = f"""asaaaaaaaaaaaaaaaa {
|
||||
// aaaaaaaaaaaa + bbbbbbbbbbbb + ccccccccccccccc + dddddddd
|
||||
// # comment
|
||||
// :.3f} cccccccccc"""
|
||||
// ```
|
||||
if comment.line_position().is_own_line()
|
||||
&& element.format_spec.is_some()
|
||||
&& comment.following_node().is_some()
|
||||
{
|
||||
return CommentPlacement::trailing(preceding, comment);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ use ruff_python_ast::{
|
|||
};
|
||||
use ruff_text_size::{Ranged, TextSlice};
|
||||
|
||||
use crate::comments::{dangling_open_parenthesis_comments, trailing_comments};
|
||||
use crate::comments::dangling_open_parenthesis_comments;
|
||||
use crate::context::{
|
||||
InterpolatedStringState, NodeLevel, WithInterpolatedStringState, WithNodeLevel,
|
||||
};
|
||||
|
@ -203,7 +203,7 @@ impl Format<PyFormatContext<'_>> for FormatInterpolatedElement<'_> {
|
|||
// # comment 27
|
||||
// :test}"
|
||||
// ```
|
||||
if comments.has_trailing_own_line(expression) {
|
||||
if comments.has_trailing(expression) {
|
||||
soft_line_break().fmt(f)?;
|
||||
}
|
||||
|
||||
|
@ -214,31 +214,6 @@ impl Format<PyFormatContext<'_>> for FormatInterpolatedElement<'_> {
|
|||
}
|
||||
}
|
||||
|
||||
// These trailing comments can only occur if the format specifier is
|
||||
// present. For example,
|
||||
//
|
||||
// ```python
|
||||
// f"{
|
||||
// x:.3f
|
||||
// # comment
|
||||
// }"
|
||||
// ```
|
||||
|
||||
// This can also be triggered outside of a format spec, at
|
||||
// least until https://github.com/astral-sh/ruff/issues/18632 is a syntax error
|
||||
// TODO(https://github.com/astral-sh/ruff/issues/18632) Remove this
|
||||
// and double check if it is still necessary for the triple quoted case
|
||||
// once this is a syntax error.
|
||||
// ```py
|
||||
// f"{
|
||||
// foo
|
||||
// :{x}
|
||||
// # comment 28
|
||||
// } woah {x}"
|
||||
// ```
|
||||
// Any other trailing comments are attached to the expression itself.
|
||||
trailing_comments(comments.trailing(self.element)).fmt(f)?;
|
||||
|
||||
if conversion.is_none() && format_spec.is_none() {
|
||||
bracket_spacing.fmt(f)?;
|
||||
}
|
||||
|
@ -258,15 +233,7 @@ impl Format<PyFormatContext<'_>> for FormatInterpolatedElement<'_> {
|
|||
let mut f = WithNodeLevel::new(NodeLevel::ParenthesizedExpression, f);
|
||||
|
||||
if self.context.is_multiline() {
|
||||
// TODO: The `or comments.has_trailing...` can be removed once newlines in format specs are a syntax error.
|
||||
// This is to support the following case:
|
||||
// ```py
|
||||
// x = f"{x !s
|
||||
// :>0
|
||||
// # comment 21
|
||||
// }"
|
||||
// ```
|
||||
if format_spec.is_none() || comments.has_trailing_own_line(self.element) {
|
||||
if format_spec.is_none() {
|
||||
group(&format_args![
|
||||
open_parenthesis_comments,
|
||||
soft_block_indent(&item)
|
||||
|
@ -276,6 +243,7 @@ impl Format<PyFormatContext<'_>> for FormatInterpolatedElement<'_> {
|
|||
// For strings ending with a format spec, don't add a newline between the end of the format spec
|
||||
// and closing curly brace because that is invalid syntax for single quoted strings and
|
||||
// the newline is preserved as part of the format spec for triple quoted strings.
|
||||
|
||||
group(&format_args![
|
||||
open_parenthesis_comments,
|
||||
indent(&format_args![soft_line_break(), item])
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue