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)
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.
@gwelymernans Thanks, that works except for the second example, where the closing parenthesis should not have its own line:
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)
Thank you!
Why did you remove this functionality with your newest commit https://github.com/google/yapf/commit/311c08719451a0cdc3a578b360293ffabb28e0d6?
The knob didn't seem to be useful anymore, because I could get the formatting you wanted here without it. Has it regressed?
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,
)
Yes, this behavior would be very nice, including the breaking before the first argument in the third example but that might be an unrelated concern.
I see what you mean. This will require a knob, though. But should be relatively straight-forward to implement.
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.
Hey, the closing bracket still has not its own line. We have DEDENT_CLOSING_BRACKETS = false so the bracket is in the same line as the last argument if there is no trailing comma. But if there is a trailing comma I want a newline for the closing bracket independent of DEDENT_CLOSING_BRACKETS.
You used my code for your test but removed this newline. I would say you want your code never look like this (independent of the setting): args,)
For some reason, I thought that you didn't want the trailing bracket on its own line. :-/
Give it a try now.
It works nearly for all of my code. Only the following lines
SETUP_REQUIRES = [
'Sphinx',
]
turned into
SETUP_REQUIRES = ['Sphinx', ]
This will be another change. Should this split happen even with a single-element tuple?
TUPLE = (
'element',
)
I think this makes only sense for lists. For single-element tuples, the trailing comma is not formatting but syntax.
Are there any changes we can try out?
Not just yet. I may be able to get to it in a few days...
Would be perfect, thanks.
I'm guessing this is the right ticket for this issue.
Given the following style arg in the command:
--style='{based_on_style: pep8, column_limit: 120, dedent_closing_brackets: 1, join_multiple_lines: 0, SPACE_BETWEEN_ENDING_COMMA_AND_CLOSING_BRACKET: 0}'
I get this reformat, which I would like to avoid:
class Meta:
- unique_together = (
- ("user", "issue"),
- ("user", "company"),
- )
+ unique_together = (("user", "issue"),
+ ("user", "company"),)
Using SPLIT_ARGUMENTS_WHEN_COMMA_TERMINATED set to 1 did not help.
Amazing tool and great work, thanks for any help.
I added this commit, which does this for lists. Please give it a try.
To https://github.com/google/yapf.git
93885e4..8e3434a master -> master
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!
I have the same problem as @silviogutierrez.
Are there any changes we can try out? :)
I've been on a vacation for the past week, so I wasn't able to focus on this too much. I looked at this a bit, and I'm not 100% sure what the best way to proceed here is....
Maybe I'm not enough familiar with your code but at some point it should look like this:
# After doing newlines depending on DEDENT_CLOSING_BRACKETS
regex_trailing_comma = r"\([^,]*,[^\n]*,([\s]*)\)"
re.sub(regex_trailing_comma, ",\n)", code)
This regex works for the following examples (tested with regex101.com):
text(a,b,sdfsdf, )
text(a,subtext(b,c),d,
)
# These ones are not selected by regex
(a,)
text(a,b,c,d)
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?
What are the current recommended knob settings for as little line breaking as possible (in function definitions and in function calls)?
Is this issue solved/feature implemented?