Split before function call in list

If the whole list cannot fit on a single line, then split before a function
call. This prevents things like this:

    def foo():
      return [
          Bar(
              xxx='some string',
              yyy='another long string',
              zzz='a third long string'), Bar(
                  xxx='some string',
                  yyy='another long string',
                  zzz='a third long string')
      ]
diff --git a/CHANGELOG b/CHANGELOG
index 5507ba0..4db4add 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -10,6 +10,8 @@
 - Increase penalty for excess characters.
 - Check that we have enough children before trying to access them all.
 - Remove trailing whitespaces from comments.
+- Split before a function call in a list if the full list isn't able to fit on
+  a single line.
 
 ## [0.16.1] 2017-03-22
 ### Changed
diff --git a/yapf/yapflib/format_decision_state.py b/yapf/yapflib/format_decision_state.py
index 3281940..b5b0409 100644
--- a/yapf/yapflib/format_decision_state.py
+++ b/yapf/yapflib/format_decision_state.py
@@ -189,6 +189,38 @@
           # Split before and dedent the closing bracket.
           return self.stack[-1].split_before_closing_bracket
 
+    if (current.is_name or current.is_string) and previous.value == ',':
+      # If the list has function calls in it and the full list itself cannot
+      # fit on the line, then we want to split. Otherwise, we'll get something
+      # like this:
+      #
+      #     X = [
+      #         Bar(xxx='some string',
+      #             yyy='another long string',
+      #             zzz='a third long string'), Bar(
+      #                 xxx='some string',
+      #                 yyy='another long string',
+      #                 zzz='a third long string')
+      #     ]
+      #
+      # or when a string formatting syntax.
+      func_call_or_string_format = False
+      if current.is_name:
+        tok = current.next_token
+        while tok and (tok.is_name or tok.value == '.'):
+          tok = tok.next_token
+        func_call_or_string_format = tok.value == '('
+      elif current.is_string:
+        tok = current.next_token
+        while tok and tok.is_string:
+          tok = tok.next_token
+        func_call_or_string_format = tok.value == '%'
+      if func_call_or_string_format:
+        open_bracket = unwrapped_line.IsSurroundedByBrackets(current)
+        if open_bracket and open_bracket.value in '[{':
+          if not self._FitsOnLine(open_bracket, open_bracket.matching_bracket):
+            return True
+
     ###########################################################################
     # Dict/Set Splitting
     if (style.Get('EACH_DICT_ENTRY_ON_SEPARATE_LINE') and
diff --git a/yapf/yapflib/format_token.py b/yapf/yapflib/format_token.py
index a396a05..de270cf 100644
--- a/yapf/yapflib/format_token.py
+++ b/yapf/yapflib/format_token.py
@@ -121,8 +121,8 @@
     """
     indent_char = '\t' if style.Get('USE_TABS') else ' '
     token_indent_char = indent_char if newlines_before > 0 else ' '
-    indent_before = (
-        indent_char * indent_level * style.Get('INDENT_WIDTH') + token_indent_char * spaces)
+    indent_before = (indent_char * indent_level * style.Get('INDENT_WIDTH') +
+                     token_indent_char * spaces)
 
     if self.is_comment:
       comment_lines = [s.lstrip() for s in self.value.splitlines()]
diff --git a/yapf/yapflib/unwrapped_line.py b/yapf/yapflib/unwrapped_line.py
index 77b2f1e..3b3210d 100644
--- a/yapf/yapflib/unwrapped_line.py
+++ b/yapf/yapflib/unwrapped_line.py
@@ -397,19 +397,19 @@
 
     if previous_token.value == '(':
       if paren_count == 0:
-        return True
+        return previous_token
       paren_count += 1
     elif previous_token.value == '{':
       if brace_count == 0:
-        return True
+        return previous_token
       brace_count += 1
     elif previous_token.value == '[':
       if sq_bracket_count == 0:
-        return True
+        return previous_token
       sq_bracket_count += 1
 
     previous_token = previous_token.previous_token
-  return False
+  return None
 
 
 _LOGICAL_OPERATORS = frozenset({'and', 'or'})
diff --git a/yapftests/reformatter_basic_test.py b/yapftests/reformatter_basic_test.py
index f06d44d..fe5d21e 100644
--- a/yapftests/reformatter_basic_test.py
+++ b/yapftests/reformatter_basic_test.py
@@ -2147,6 +2147,33 @@
     uwlines = yapf_test_helper.ParseAndUnwrap(code)
     self.assertCodeEqual(code, reformatter.Reformat(uwlines))
 
+  def testListWithFunctionCalls(self):
+    unformatted_code = textwrap.dedent("""\
+        def foo():
+          return [
+              Bar(
+                  xxx='some string',
+                  yyy='another long string',
+                  zzz='a third long string'), Bar(
+                      xxx='some string',
+                      yyy='another long string',
+                      zzz='a third long string')
+          ]
+        """)
+    expected_code = textwrap.dedent("""\
+        def foo():
+          return [
+              Bar(xxx='some string',
+                  yyy='another long string',
+                  zzz='a third long string'),
+              Bar(xxx='some string',
+                  yyy='another long string',
+                  zzz='a third long string')
+          ]
+        """)
+    uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+    self.assertEqual(expected_code, reformatter.Reformat(uwlines))
+
 
 if __name__ == '__main__':
   unittest.main()
diff --git a/yapftests/reformatter_buganizer_test.py b/yapftests/reformatter_buganizer_test.py
index 1bdac25..8eed74b 100644
--- a/yapftests/reformatter_buganizer_test.py
+++ b/yapftests/reformatter_buganizer_test.py
@@ -28,6 +28,45 @@
   def setUpClass(cls):
     style.SetGlobalStyle(style.CreateChromiumStyle())
 
+  def testB36806207(self):
+    unformatted_code = textwrap.dedent("""\
+        def _():
+          linearity_data = [[row] for row in [
+              "%.1f mm" % (np.mean(linearity_values["pos_error"]) * 1000.0),
+              "%.1f mm" % (np.max(linearity_values["pos_error"]) * 1000.0),
+              "%.1f mm" % (np.mean(linearity_values["pos_error_chunk_mean"]) * 1000.0),
+              "%.1f mm" % (np.max(linearity_values["pos_error_chunk_max"]) * 1000.0),
+              "%.1f deg" % math.degrees(np.mean(linearity_values["rot_noise"])),
+              "%.1f deg" % math.degrees(np.max(linearity_values["rot_noise"])),
+              "%.1f deg" % math.degrees(np.mean(linearity_values["rot_drift"])),
+              "%.1f deg" % math.degrees(np.max(linearity_values["rot_drift"])),
+              "%.1f%%" % (np.max(linearity_values["pos_discontinuity"]) * 100.0),
+              "%.1f%%" % (np.max(linearity_values["rot_discontinuity"]) * 100.0)
+          ]]
+        """)
+    expected_code = textwrap.dedent("""\
+        def _():
+          linearity_data = [
+              [row]
+              for row in [
+                  "%.1f mm" % (np.mean(linearity_values["pos_error"]) * 1000.0),
+                  "%.1f mm" % (np.max(linearity_values["pos_error"]) * 1000.0),
+                  "%.1f mm" % (
+                      np.mean(linearity_values["pos_error_chunk_mean"]) * 1000.0),
+                  "%.1f mm" % (
+                      np.max(linearity_values["pos_error_chunk_max"]) * 1000.0),
+                  "%.1f deg" % math.degrees(np.mean(linearity_values["rot_noise"])),
+                  "%.1f deg" % math.degrees(np.max(linearity_values["rot_noise"])),
+                  "%.1f deg" % math.degrees(np.mean(linearity_values["rot_drift"])),
+                  "%.1f deg" % math.degrees(np.max(linearity_values["rot_drift"])),
+                  "%.1f%%" % (np.max(linearity_values["pos_discontinuity"]) * 100.0),
+                  "%.1f%%" % (np.max(linearity_values["rot_discontinuity"]) * 100.0)
+              ]
+          ]
+        """)
+    uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+    self.assertEqual(expected_code, reformatter.Reformat(uwlines))
+
   def testB36215507(self):
     code = textwrap.dedent("""\
         class X():