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(