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__':