SPLIT_ALL_TOP_LEVEL_COMMA_SEPARATED_VALUES and FORCE_MULTILINE_DICT interaction (#1103)
* SPLIT_ALL_TOP_LEVEL_COMMA_SEPARATED_VALUES and FORCE_MULTILINE_DICT interaction
* explicitly defined FORCE_MULTILINE_DICT to override SPLIT_ALL_TOP_LEVEL_COMMA_SEPARATED_VALUES
* added tests to account for the interaction of these two knobs
* * fix formatting
* Updated changelog
diff --git a/CHANGELOG b/CHANGELOG
index 4dc2d1e..70b3c9b 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -6,6 +6,7 @@
### Changes
- The verification module has been removed. NOTE: this changes the public APIs
by removing the "verify" parameter.
+- Changed FORCE_MULTILINE_DICT to override SPLIT_ALL_TOP_LEVEL_COMMA_SEPARATED_VALUES.
## [0.40.1] 2023-06-20
### Fixed
diff --git a/yapf/yapflib/format_decision_state.py b/yapf/yapflib/format_decision_state.py
index 0c8643f..a0d7033 100644
--- a/yapf/yapflib/format_decision_state.py
+++ b/yapf/yapflib/format_decision_state.py
@@ -181,6 +181,10 @@
if style.Get('SPLIT_ALL_COMMA_SEPARATED_VALUES') and previous.value == ',':
return True
+ if (style.Get('FORCE_MULTILINE_DICT') and
+ subtypes.DICTIONARY_KEY in current.subtypes and not current.is_comment):
+ return True
+
if (style.Get('SPLIT_ALL_TOP_LEVEL_COMMA_SEPARATED_VALUES') and
previous.value == ','):
# Avoid breaking in a container that fits in the current line if possible
diff --git a/yapftests/reformatter_basic_test.py b/yapftests/reformatter_basic_test.py
index cf8cfe4..aae46d6 100644
--- a/yapftests/reformatter_basic_test.py
+++ b/yapftests/reformatter_basic_test.py
@@ -110,10 +110,10 @@
self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
def testSplittingTopLevelAllArgs(self):
- style.SetGlobalStyle(
- style.CreateStyleFromConfig(
- '{split_all_top_level_comma_separated_values: true, '
- 'column_limit: 40}'))
+ style_dict = style.CreateStyleFromConfig(
+ '{split_all_top_level_comma_separated_values: true, '
+ 'column_limit: 40}')
+ style.SetGlobalStyle(style_dict)
# Works the same way as split_all_comma_separated_values
unformatted_code = textwrap.dedent("""\
responseDict = {"timestamp": timestamp, "someValue": value, "whatever": 120}
@@ -193,6 +193,48 @@
llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
+ # This tests when there is an embedded dictionary that will fit in a line
+ original_multiline = style_dict['FORCE_MULTILINE_DICT']
+ style_dict['FORCE_MULTILINE_DICT'] = False
+ style.SetGlobalStyle(style_dict)
+ unformatted_code = textwrap.dedent("""\
+ someLongFunction(this_is_a_very_long_parameter,
+ abc={a: b, b: c})
+ """)
+ expected_formatted_code = textwrap.dedent("""\
+ someLongFunction(
+ this_is_a_very_long_parameter,
+ abc={
+ a: b, b: c
+ })
+ """)
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ actual_formatted_code = reformatter.Reformat(llines)
+ self.assertCodeEqual(expected_formatted_code, actual_formatted_code)
+
+ # This tests when there is an embedded dictionary that will fit in a line,
+ # but FORCE_MULTILINE_DICT is set
+ style_dict['FORCE_MULTILINE_DICT'] = True
+ style.SetGlobalStyle(style_dict)
+ unformatted_code = textwrap.dedent("""\
+ someLongFunction(this_is_a_very_long_parameter,
+ abc={a: b, b: c})
+ """)
+ expected_formatted_code = textwrap.dedent("""\
+ someLongFunction(
+ this_is_a_very_long_parameter,
+ abc={
+ a: b,
+ b: c
+ })
+ """)
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ actual_formatted_code = reformatter.Reformat(llines)
+ self.assertCodeEqual(expected_formatted_code, actual_formatted_code)
+
+ style_dict['FORCE_MULTILINE_DICT'] = original_multiline
+ style.SetGlobalStyle(style_dict)
+
# Exercise the case where there's no opening bracket (for a, b)
unformatted_code = textwrap.dedent("""\
a, b = f(