google / google/yapf

How to adjust code (perhaps `Visit_trailer`?) to induce splitting at dot when previous character is a closing bracket ?

Open
#903 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
Python
Stars
14k
Forks
904
PR merge metrics
No merged PRs in 30d

Description

My code uses a lot of data processing and transformations using pandas, here is an example of what I am trying to adjust yapf for

```
df_final = (
pd.concat([df1, df2, df3])
[['col1', 'col2']]
.query("~(col0 & (text.str.lower() == text))")
.assign(newcol=lambda x: df4.reindex(x.entity).fillna(0).values)
.merge(df5, how="left", indicator=True)
.drop(columns=["old"])
[["col4", "col5"]]
.assign(
a=lambda x: x+1,
b=lambda x: x+2,
c=lambda x: x+3,
)
.sort_values(
["a", "b", "c"],
ascending=[False, True, False]
)
.drop_duplicates()
.reset_index(drop=True)
)
```

Having each pandas method or column filter in it's own line makes the data flows very easy for me to read.

I attempted to use these settings to try to maintain this style in vscode

```
"python.formatting.yapfArgs": [
"--style",
"{based_on_style: google, column_limit: 88, SPLIT_BEFORE_DOT: True, indent_width: 4, SPLIT_PENALTY_AFTER_OPENING_BRACKET: 0 , split_penalty_for_added_line_split: 0, split_before_closing_bracket: False, split_before_dict_set_generator: True, ALIGN_CLOSING_BRACKET_WITH_VISUAL_INDENT: True, ALLOW_SPLIT_BEFORE_DEFAULT_OR_NAMED_ASSIGNS: True, COALESCE_BRACKETS: True, DEDENT_CLOSING_BRACKETS: True, JOIN_MULTIPLE_LINES: False, SPLIT_BEFORE_BITWISE_OPERATOR: True, ALLOW_MULTILINE_DICTIONARY_KEYS: True, SPLIT_BEFORE_EXPRESSION_AFTER_OPENING_PAREN: True, SPLIT_BEFORE_FIRST_ARGUMENT: True, SPLIT_BEFORE_LOGICAL_OPERATOR: True, SPLIT_COMPLEX_COMPREHENSION: True, SPLIT_PENALTY_ARITHMETIC_OPERATOR: 200, SPLIT_PENALTY_COMPREHENSION: 70, SPLIT_PENALTY_FOR_ADDED_LINE_SPLIT: 0, SPLIT_PENALTY_LOGICAL_OPERATOR:80}"
]
```

And then I also attempted to fork this branch and adjust the code further, specifically starting at these lines https://github.com/Santosh-Gupta/yapf/blob/main/yapf/yapflib/split_penalty.py#L212

```
def Visit_trailer(self, node): # pylint: disable=invalid-name
# trailer ::= '(' [arglist] ')' | '[' subscriptlist ']' | '.' NAME
if node.children[0].value == '.':
before = style.Get('SPLIT_BEFORE_DOT')
if node.children[-1].value == ')' or node.children[-1].value == ']':
BEFORE_PENALITY = CONNECTED
else:
BEFORE_PENALITY = VERY_STRONGLY_CONNECTED
_SetSplitPenalty(node.children[0],
BEFORE_PENALITY if before else DOTTED_NAME)
_SetSplitPenalty(node.children[1],
DOTTED_NAME if before else BEFORE_PENALITY)
_SetSplitPenalty(node.children[-1],
DOTTED_NAME if before else BEFORE_PENALITY)
```

What I was trying to do is look for parts in the code where a dot comes after a closing bracket, and in those cases decrease the split penalty for the dot, and increase it for the characters before and after the text.

With these adjustments, the splitting still occurs at the parenthesis. Here's what it does with settings and code above

```
df_final = (
pd.concat([df1, df2, df3])[[
'col1', 'col2'
]].query("~(col0 & (text.str.lower() == text))").assign(
newcol=lambda x: df4.reindex(x.entity).fillna(0).values
).merge(df5, how="left",
indicator=True).drop(columns=["old"])[["col4", "col5"]].assign(
a=lambda x: x + 1,
b=lambda x: x + 2,
c=lambda x: x + 3,
).sort_values(["a", "b", "c"], ascending=[
False, True, False
]).drop_duplicates().reset_index(drop=True)
)
```

I am wondering if the parts of the code I adjusted are being override by some other part of the code. Or if the logic in my code is off. Or something else entirely.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.