Respect indent when measuring with MeasureMode::AllLines (#6120)

This commit is contained in:
Micha Reiser 2023-07-27 13:34:36 +02:00 committed by Charlie Marsh
parent 9574ff3dc7
commit 6bf6646c5d
5 changed files with 109 additions and 51 deletions

View file

@ -116,7 +116,6 @@ impl<'a> Printer<'a> {
self.print_str("\n"); self.print_str("\n");
} }
self.state.pending_space = false;
self.state.pending_indent = args.indention(); self.state.pending_indent = args.indention();
} }
} }
@ -744,7 +743,6 @@ struct PrinterState<'a> {
source_markers: Vec<SourceMarker>, source_markers: Vec<SourceMarker>,
source_position: TextSize, source_position: TextSize,
pending_indent: Indention, pending_indent: Indention,
pending_space: bool,
measured_group_fits: bool, measured_group_fits: bool,
generated_line: usize, generated_line: usize,
generated_column: usize, generated_column: usize,
@ -1009,12 +1007,12 @@ impl<'a, 'print> FitsMeasurer<'a, 'print> {
let args = self.stack.top(); let args = self.stack.top();
match element { match element {
FormatElement::Space => return Ok(self.fits_text(" ")), FormatElement::Space => return Ok(self.fits_text(" ", args)),
FormatElement::Line(line_mode) => { FormatElement::Line(line_mode) => {
match args.mode() { match args.mode() {
PrintMode::Flat => match line_mode { PrintMode::Flat => match line_mode {
LineMode::SoftOrSpace => return Ok(self.fits_text(" ")), LineMode::SoftOrSpace => return Ok(self.fits_text(" ", args)),
LineMode::Soft => {} LineMode::Soft => {}
LineMode::Hard | LineMode::Empty => { LineMode::Hard | LineMode::Empty => {
return Ok(if self.must_be_flat { return Ok(if self.must_be_flat {
@ -1036,17 +1034,18 @@ impl<'a, 'print> FitsMeasurer<'a, 'print> {
MeasureMode::AllLines => { MeasureMode::AllLines => {
// Continue measuring on the next line // Continue measuring on the next line
self.state.line_width = 0; self.state.line_width = 0;
self.state.pending_indent = args.indention();
} }
} }
} }
} }
} }
FormatElement::StaticText { text } => return Ok(self.fits_text(text)), FormatElement::StaticText { text } => return Ok(self.fits_text(text, args)),
FormatElement::DynamicText { text, .. } => return Ok(self.fits_text(text)), FormatElement::DynamicText { text, .. } => return Ok(self.fits_text(text, args)),
FormatElement::SourceCodeSlice { slice, .. } => { FormatElement::SourceCodeSlice { slice, .. } => {
let text = slice.text(self.printer.source_code); let text = slice.text(self.printer.source_code);
return Ok(self.fits_text(text)); return Ok(self.fits_text(text, args));
} }
FormatElement::LineSuffixBoundary => { FormatElement::LineSuffixBoundary => {
if self.state.has_line_suffix { if self.state.has_line_suffix {
@ -1255,7 +1254,7 @@ impl<'a, 'print> FitsMeasurer<'a, 'print> {
Ok(Fits::Maybe) Ok(Fits::Maybe)
} }
fn fits_text(&mut self, text: &str) -> Fits { fn fits_text(&mut self, text: &str, args: PrintElementArgs) -> Fits {
let indent = std::mem::take(&mut self.state.pending_indent); let indent = std::mem::take(&mut self.state.pending_indent);
self.state.line_width += indent.level() as usize * self.options().indent_width() as usize self.state.line_width += indent.level() as usize * self.options().indent_width() as usize
+ indent.align() as usize; + indent.align() as usize;
@ -1264,10 +1263,17 @@ impl<'a, 'print> FitsMeasurer<'a, 'print> {
let char_width = match c { let char_width = match c {
'\t' => self.options().tab_width as usize, '\t' => self.options().tab_width as usize,
'\n' => { '\n' => {
return if self.must_be_flat { if self.must_be_flat {
Fits::No return Fits::No;
} else { } else {
Fits::Yes match args.measure_mode() {
MeasureMode::FirstLine => return Fits::Yes,
MeasureMode::AllLines => {
self.state.line_width = 0;
self.state.pending_indent = args.indention();
continue;
}
}
}; };
} }
c => c.width().unwrap_or(0), c => c.width().unwrap_or(0),

View file

@ -75,7 +75,7 @@ impl FormatNodeRule<ExprAttribute> for FormatExprAttribute {
impl NeedsParentheses for ExprAttribute { impl NeedsParentheses for ExprAttribute {
fn needs_parentheses( fn needs_parentheses(
&self, &self,
parent: AnyNodeRef, _parent: AnyNodeRef,
context: &PyFormatContext, context: &PyFormatContext,
) -> OptionalParentheses { ) -> OptionalParentheses {
// Checks if there are any own line comments in an attribute chain (a.b.c). // Checks if there are any own line comments in an attribute chain (a.b.c).
@ -88,7 +88,7 @@ impl NeedsParentheses for ExprAttribute {
{ {
OptionalParentheses::Always OptionalParentheses::Always
} else { } else {
self.value.needs_parentheses(parent, context) self.value.needs_parentheses(self.into(), context)
} }
} }
} }

View file

@ -119,10 +119,10 @@ impl FormatNodeRule<ExprCall> for FormatExprCall {
impl NeedsParentheses for ExprCall { impl NeedsParentheses for ExprCall {
fn needs_parentheses( fn needs_parentheses(
&self, &self,
parent: AnyNodeRef, _parent: AnyNodeRef,
context: &PyFormatContext, context: &PyFormatContext,
) -> OptionalParentheses { ) -> OptionalParentheses {
self.func.needs_parentheses(parent, context) self.func.needs_parentheses(self.into(), context)
} }
} }

View file

@ -203,18 +203,41 @@ class C:
print(i) print(i)
xxxxxxxxxxxxxxxx = Yyyy2YyyyyYyyyyy( xxxxxxxxxxxxxxxx = Yyyy2YyyyyYyyyyy(
push_manager=context.request.resource_manager, push_manager=context.request.resource_manager,
@@ -120,9 +120,7 @@ @@ -110,19 +110,20 @@
key7: value7, value, is_going_to_be="too long to fit in a single line", srsly=True
key8: value8, ), "Not what we expected"
key9: value9,
- assert {
- key1: value1,
- key2: value2,
- key3: value3,
- key4: value4,
- key5: value5,
- key6: value6,
- key7: value7,
- key8: value8,
- key9: value9,
- } == expected, ( - } == expected, (
- "Not what we expected and the message is too long to fit in one line" - "Not what we expected and the message is too long to fit in one line"
- ) - )
+ } == expected, "Not what we expected and the message is too long to fit in one line" + assert (
+ {
+ key1: value1,
+ key2: value2,
+ key3: value3,
+ key4: value4,
+ key5: value5,
+ key6: value6,
+ key7: value7,
+ key8: value8,
+ key9: value9,
+ }
+ == expected
+ ), "Not what we expected and the message is too long to fit in one line"
assert expected( assert expected(
value, is_going_to_be="too long to fit in a single line", srsly=True value, is_going_to_be="too long to fit in a single line", srsly=True
@@ -153,7 +151,8 @@ @@ -153,7 +154,8 @@
" because it's too long" " because it's too long"
) )
@ -224,7 +247,7 @@ class C:
%3d 0 LOAD_FAST 1 (x) %3d 0 LOAD_FAST 1 (x)
2 LOAD_CONST 1 (1) 2 LOAD_CONST 1 (1)
4 COMPARE_OP 2 (==) 4 COMPARE_OP 2 (==)
@@ -161,8 +160,8 @@ @@ -161,8 +163,8 @@
8 STORE_ATTR 0 (x) 8 STORE_ATTR 0 (x)
10 LOAD_CONST 0 (None) 10 LOAD_CONST 0 (None)
12 RETURN_VALUE 12 RETURN_VALUE
@ -352,17 +375,20 @@ class C:
value, is_going_to_be="too long to fit in a single line", srsly=True value, is_going_to_be="too long to fit in a single line", srsly=True
), "Not what we expected" ), "Not what we expected"
assert { assert (
key1: value1, {
key2: value2, key1: value1,
key3: value3, key2: value2,
key4: value4, key3: value3,
key5: value5, key4: value4,
key6: value6, key5: value5,
key7: value7, key6: value6,
key8: value8, key7: value7,
key9: value9, key8: value8,
} == expected, "Not what we expected and the message is too long to fit in one line" key9: value9,
}
== expected
), "Not what we expected and the message is too long to fit in one line"
assert expected( assert expected(
value, is_going_to_be="too long to fit in a single line", srsly=True value, is_going_to_be="too long to fit in a single line", srsly=True

View file

@ -203,18 +203,41 @@ class C:
print(i) print(i)
xxxxxxxxxxxxxxxx = Yyyy2YyyyyYyyyyy( xxxxxxxxxxxxxxxx = Yyyy2YyyyyYyyyyy(
push_manager=context.request.resource_manager, push_manager=context.request.resource_manager,
@@ -120,9 +120,7 @@ @@ -110,19 +110,20 @@
key7: value7, value, is_going_to_be="too long to fit in a single line", srsly=True
key8: value8, ), "Not what we expected"
key9: value9,
- assert {
- key1: value1,
- key2: value2,
- key3: value3,
- key4: value4,
- key5: value5,
- key6: value6,
- key7: value7,
- key8: value8,
- key9: value9,
- } == expected, ( - } == expected, (
- "Not what we expected and the message is too long to fit in one line" - "Not what we expected and the message is too long to fit in one line"
- ) - )
+ } == expected, "Not what we expected and the message is too long to fit in one line" + assert (
+ {
+ key1: value1,
+ key2: value2,
+ key3: value3,
+ key4: value4,
+ key5: value5,
+ key6: value6,
+ key7: value7,
+ key8: value8,
+ key9: value9,
+ }
+ == expected
+ ), "Not what we expected and the message is too long to fit in one line"
assert expected( assert expected(
value, is_going_to_be="too long to fit in a single line", srsly=True value, is_going_to_be="too long to fit in a single line", srsly=True
@@ -153,7 +151,8 @@ @@ -153,7 +154,8 @@
" because it's too long" " because it's too long"
) )
@ -224,7 +247,7 @@ class C:
%3d 0 LOAD_FAST 1 (x) %3d 0 LOAD_FAST 1 (x)
2 LOAD_CONST 1 (1) 2 LOAD_CONST 1 (1)
4 COMPARE_OP 2 (==) 4 COMPARE_OP 2 (==)
@@ -161,8 +160,8 @@ @@ -161,8 +163,8 @@
8 STORE_ATTR 0 (x) 8 STORE_ATTR 0 (x)
10 LOAD_CONST 0 (None) 10 LOAD_CONST 0 (None)
12 RETURN_VALUE 12 RETURN_VALUE
@ -352,17 +375,20 @@ class C:
value, is_going_to_be="too long to fit in a single line", srsly=True value, is_going_to_be="too long to fit in a single line", srsly=True
), "Not what we expected" ), "Not what we expected"
assert { assert (
key1: value1, {
key2: value2, key1: value1,
key3: value3, key2: value2,
key4: value4, key3: value3,
key5: value5, key4: value4,
key6: value6, key5: value5,
key7: value7, key6: value6,
key8: value8, key7: value7,
key9: value9, key8: value8,
} == expected, "Not what we expected and the message is too long to fit in one line" key9: value9,
}
== expected
), "Not what we expected and the message is too long to fit in one line"
assert expected( assert expected(
value, is_going_to_be="too long to fit in a single line", srsly=True value, is_going_to_be="too long to fit in a single line", srsly=True