yapf: Line breaking behavior for function arguments with and without trailing comma

Hello and thanks for YAPF. It’s been working nicely for us, except for the formatting of long function arguments. Take a look at the example below. If a trailing comma is present, we would like to keep the them in individual lines. Without trailing comma, an option to break right after the opening parenthesis would be nice. This is PEP8 conform (as is the the YAPF output) and plays more nicely with with long function names.

Desired format:

a_very_long_function_name(
    long_argument_name_1=1,
    long_argument_name_2=2,
    long_argument_name_3=3,
    long_argument_name_4=4,
)

a_very_long_function_name(
    long_argument_name_1=1, long_argument_name_2=2,
    long_argument_name_3=3, long_argument_name_4=4)

YAPF output:

a_very_long_function_name(long_argument_name_1=1,
                          long_argument_name_2=2,
                          long_argument_name_3=3,
                          long_argument_name_4=4, )

a_very_long_function_name(long_argument_name_1=1,
                          long_argument_name_2=2,
                          long_argument_name_3=3,
                          long_argument_name_4=4)

About this issue

  • Original URL
  • State: open
  • Created 8 years ago
  • Reactions: 22
  • Comments: 27 (9 by maintainers)

Most upvoted comments

Hello! I have been evaluating bringing in yapf to a few projects. I found this thread and realized that the this issue applies to my current adoption. Has there been any resolutions, updates, or work-arounds discovered?

Maybe there was a misunderstanding what behavior we would like a trailing comma to cause. If there is a trailing comma, each argument and the closing parenthesis should have their own lines to easily edit individual arguments (regardless of line length and DEDENT_CLOSING_BRACKETS knob). Some examples to illustrate:

function_name(argument_name_1=1, argument_name_2=2, argument_name_3=3)

# Break even though this would fit into a single line.
function_name(
    argument_name_1=1,
    argument_name_2=2,
    argument_name_3=3,
)

a_very_long_function_name(
    long_argument_name_1=1, long_argument_name_2=2, long_argument_name_3=3,
    long_argument_name_4=4)

a_very_long_function_name(
    long_argument_name_1=1,
    long_argument_name_2=2,
    long_argument_name_3=3,
    long_argument_name_4=4,
)

What may help you get further towards the desired output is specifying SPLIT_BEFORE_NAMED_ASSIGNS: False. When I add that, it gives this:

$ python -m yapf --style='{based_on_style: pep8; SPLIT_BEFORE_NAMED_ASSIGNS: False}' /tmp/x.py
a_very_long_function_name(long_argument_name_1=1,
                          long_argument_name_2=2,
                          long_argument_name_3=3,
                          long_argument_name_4=4, )

a_very_long_function_name(long_argument_name_1=1, long_argument_name_2=2,
                          long_argument_name_3=3, long_argument_name_4=4)

There is another option you can set that can get you further:

$ python -m yapf --style='{based_on_style: pep8; SPLIT_BEFORE_NAMED_ASSIGNS: False, DEDENT_CLOSING_BRACKETS: True}' /tmp/x.py
a_very_long_function_name(
    long_argument_name_1=1,
    long_argument_name_2=2,
    long_argument_name_3=3,
    long_argument_name_4=4,
)

a_very_long_function_name(
    long_argument_name_1=1, long_argument_name_2=2, long_argument_name_3=3,
    long_argument_name_4=4
)

Please let me know if that works for you.

Okay. I added a new knob SPLIT_ARGUMENTS_WHEN_COMMA_TERMINATED which should do what you want. Please try it out on top-of-tree.

What are the current recommended knob settings for as little line breaking as possible (in function definitions and in function calls)?

So with this yapf config:

[style]
based_on_style = pep8
column_limit = 120
dedent_closing_brackets = true
join_multiple_lines = false
space_between_ending_comma_and_closing_bracket = false
split_arguments_when_comma_terminated = true

I now get this:


     class Meta:
-        unique_together = (
-            ("user", "issue"),
-            ("user", "company"),
-        )
+        unique_together = (("user", "issue"),
+                           ("user", "company"),)

But also this:


-        self.assertQuerysetEqual(issues, map(repr, [issue1, issue2]), ordered=False)
+        self.assertQuerysetEqual(issues, map(repr,
+                                             [
+                                                 issue1,
+                                                 issue2
+                                             ]), ordered=False)

Both suggestions are kind of odd. I would expect both examples to stay as is, unless they are over the line length limit. But maybe we have a very particular in-house style. Thanks for the updates!

Is this issue solved/feature implemented?