Don't split too aggressively with named assigns

If a function call that has a named assign is part of an argument list,
don't cause the other arguments to split just because it has a named
assign. I.e., 'a' won't be forced to split here:

  func(a, b, c, d(x, y, z=42))
diff --git a/CHANGELOG b/CHANGELOG
index 47f9f03..1b7e55e 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -2,6 +2,14 @@
 # All notable changes to this project will be documented in this file.
 # This project adheres to [Semantic Versioning](http://semver.org/).
 
+## [0.15.2] UNRELEASED
+### Fixed
+- Don't perform a global split when a named assign is part of a function call
+  which itself is an argument to a function call. I.e., don't cause 'a' to
+  split here:
+
+      func(a, b, c, d(x, y, z=42))
+
 ## [0.15.1] 2017-01-21
 ### Fixed
 - Don't insert a space between a type hint and the '=' sign.
diff --git a/yapf/yapflib/comment_splicer.py b/yapf/yapflib/comment_splicer.py
index 4559bde..a7b37a8 100644
--- a/yapf/yapflib/comment_splicer.py
+++ b/yapf/yapflib/comment_splicer.py
@@ -78,8 +78,7 @@
                     comment_prefix,
                     comment_lineno,
                     comment_column,
-                    standalone=False),
-                prev_leaf[0])
+                    standalone=False), prev_leaf[0])
           elif child.type == token.DEDENT:
             # Comment prefixes on DEDENT nodes also deserve special treatment,
             # because their final placement depends on their prefix.
@@ -124,8 +123,7 @@
                       '\n'.join(before) + '\n',
                       comment_lineno,
                       comment_column,
-                      standalone=True),
-                  ancestor_at_indent)
+                      standalone=True), ancestor_at_indent)
               if after:
                 after_column = len(after[0]) - len(after[0].lstrip())
                 comment_column -= comment_column - after_column
@@ -134,16 +132,14 @@
                         '\n'.join(after) + '\n',
                         after_lineno,
                         comment_column,
-                        standalone=True),
-                    _FindNextAncestor(ancestor_at_indent))
+                        standalone=True), _FindNextAncestor(ancestor_at_indent))
             else:
               pytree_utils.InsertNodesAfter(
                   _CreateCommentsFromPrefix(
                       comment_prefix,
                       comment_lineno,
                       comment_column,
-                      standalone=True),
-                  ancestor_at_indent)
+                      standalone=True), ancestor_at_indent)
           else:
             # Otherwise there are two cases.
             #
diff --git a/yapf/yapflib/format_decision_state.py b/yapf/yapflib/format_decision_state.py
index df4e24e..3bd3b36 100644
--- a/yapf/yapflib/format_decision_state.py
+++ b/yapf/yapflib/format_decision_state.py
@@ -192,11 +192,25 @@
           #  a(
           #      b=1,
           #      c=2)
-          indent_amt = self.stack[-1].indent * style.Get('INDENT_WIDTH')
-          pptoken = previous.previous_token
-          opening_column = len(pptoken.value) if pptoken else 0 - indent_amt - 1
           if previous.value == '(':
-            return opening_column >= style.Get('CONTINUATION_INDENT_WIDTH')
+            if (self._FitsOnLine(previous, previous.matching_bracket) and
+                unwrapped_line.IsSurroundedByBrackets(previous)):
+              # An argument to a function is a function call with named
+              # assigns.
+              return False
+
+            func_start = previous.previous_token
+            while func_start and func_start.previous_token:
+              prev = func_start.previous_token
+              if not prev.is_name and prev.value != '.':
+                break
+              func_start = prev
+
+            if func_start:
+              func_name_len = previous.total_length - func_start.total_length
+              func_name_len += len(func_start.value)
+              return func_name_len > style.Get('CONTINUATION_INDENT_WIDTH')
+
           opening = _GetOpeningBracket(current)
           if opening:
             arglist_length = (opening.matching_bracket.total_length -
diff --git a/yapf/yapflib/subtype_assigner.py b/yapf/yapflib/subtype_assigner.py
index f9277dc..155994a 100644
--- a/yapf/yapflib/subtype_assigner.py
+++ b/yapf/yapflib/subtype_assigner.py
@@ -313,7 +313,8 @@
       return False
     has_subtype = False
     for child in node.children:
-      has_subtype |= HasDefaultOrNamedAssignSubtype(child)
+      if pytree_utils.NodeName(child) != 'arglist':
+        has_subtype |= HasDefaultOrNamedAssignSubtype(child)
     return has_subtype
 
   if HasDefaultOrNamedAssignSubtype(node):
diff --git a/yapftests/reformatter_basic_test.py b/yapftests/reformatter_basic_test.py
index 85d2931..f180ace 100644
--- a/yapftests/reformatter_basic_test.py
+++ b/yapftests/reformatter_basic_test.py
@@ -1946,6 +1946,24 @@
     uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
     self.assertEqual(expected_code, reformatter.Reformat(uwlines))
 
+  def testNamedAssignNotAtEndOfLine(self):
+    unformatted_code = textwrap.dedent("""\
+        def _():
+          if True:
+            with py3compat.open_with_encoding(filename, mode='w',
+                                              encoding=encoding) as fd:
+              pass
+        """)
+    expected_code = textwrap.dedent("""\
+        def _():
+          if True:
+            with py3compat.open_with_encoding(
+                filename, mode='w', encoding=encoding) as fd:
+              pass
+        """)
+    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 57c9428..79d0641 100644
--- a/yapftests/reformatter_buganizer_test.py
+++ b/yapftests/reformatter_buganizer_test.py
@@ -28,6 +28,17 @@
   def setUpClass(cls):
     style.SetGlobalStyle(style.CreateChromiumStyle())
 
+  def testB34682902(self):
+    unformatted_code = textwrap.dedent("""\
+        logging.info("Mean angular velocity norm: %.3f", np.linalg.norm(np.mean(ang_vel_arr, axis=0)))
+        """)
+    expected_formatted_code = textwrap.dedent("""\
+        logging.info("Mean angular velocity norm: %.3f",
+                     np.linalg.norm(np.mean(ang_vel_arr, axis=0)))
+        """)
+    uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+    self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+
   def testB33842726(self):
     unformatted_code = textwrap.dedent("""\
         class _():
@@ -407,12 +418,9 @@
     expected_formatted_code = textwrap.dedent("""\
         if True:
           query.fetch_page.assert_has_calls([
-              mock.call(
-                  100, start_cursor=None),
-              mock.call(
-                  100, start_cursor=cursor_1),
-              mock.call(
-                  100, start_cursor=cursor_2),
+              mock.call(100, start_cursor=None),
+              mock.call(100, start_cursor=cursor_1),
+              mock.call(100, start_cursor=cursor_2),
           ])
         """)
     uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
@@ -696,13 +704,10 @@
                        (1 - m.ffffffffffffffff(llllllllllllllllllllll * 1000000, m.vvv))
                        * m.ddddddddddddddddd(m.vvv)), m.fffff(
                            m.rrr('mmmmmmmmmmmmmmmm', 'sssssssssssssssssssssss'),
-                           dict(
-                               ffffffffffffffff,
-                               **{
-                                   'mmmmmm:ssssss':
-                                       m.rrrrrrrrrrr(
-                                           '|'.join(iiiiiiiiiiiiii), iiiiii=True)
-                               }))
+                           dict(ffffffffffffffff, **{
+                               'mmmmmm:ssssss':
+                                   m.rrrrrrrrrrr('|'.join(iiiiiiiiiiiiii), iiiiii=True)
+                           }))
                    | m.wwwwww(m.rrrr('1h'))
                    | m.ggggggg(bbbbbbbbbbbbbbb))
                   | m.jjjj()
@@ -965,8 +970,9 @@
 
   def testB19194420(self):
     code = textwrap.dedent("""\
-        method.Set('long argument goes here that causes the line to break',
-                   lambda arg2=0.5: arg2)
+        method.Set(
+            'long argument goes here that causes the line to break',
+            lambda arg2=0.5: arg2)
         """)
     uwlines = yapf_test_helper.ParseAndUnwrap(code)
     self.assertCodeEqual(code, reformatter.Reformat(uwlines))
diff --git a/yapftests/reformatter_verify_test.py b/yapftests/reformatter_verify_test.py
index dd1d60f..a585c3b 100644
--- a/yapftests/reformatter_verify_test.py
+++ b/yapftests/reformatter_verify_test.py
@@ -51,9 +51,8 @@
             pass
         """)
     uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
-    self.assertCodeEqual(
-        expected_formatted_code, reformatter.Reformat(
-            uwlines, verify=False))
+    self.assertCodeEqual(expected_formatted_code,
+                         reformatter.Reformat(uwlines, verify=False))
 
   def testVerifyFutureImport(self):
     unformatted_code = textwrap.dedent("""\
@@ -81,9 +80,8 @@
             call_my_function(print)
         """)
     uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
-    self.assertCodeEqual(
-        expected_formatted_code, reformatter.Reformat(
-            uwlines, verify=False))
+    self.assertCodeEqual(expected_formatted_code,
+                         reformatter.Reformat(uwlines, verify=False))
 
   def testContinuationLineShouldBeDistinguished(self):
     unformatted_code = textwrap.dedent("""\
@@ -102,9 +100,8 @@
                     pass
         """)
     uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
-    self.assertCodeEqual(
-        expected_formatted_code, reformatter.Reformat(
-            uwlines, verify=False))
+    self.assertCodeEqual(expected_formatted_code,
+                         reformatter.Reformat(uwlines, verify=False))
 
 
 if __name__ == '__main__':