Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Apply more granular changes by using # fmt: skip #391

Open
wants to merge 3 commits into
base: master
Choose a base branch
from

Conversation

wkentaro
Copy link

@wkentaro wkentaro commented Sep 4, 2022

Close #388

@akaihola What do you think of this solution? (NOTE: this won't work with nonstandard indentations)

Before

image

After

image

Limitations

Screen Shot 2022-09-05 at 2 42 32

@akaihola
Copy link
Owner

akaihola commented Sep 4, 2022

@wkentaro indeed an interesting approach!

In some test cases, the end result seems to be different, see build #1419. Do you think these are in fact improvements to old behavior instead of erroneous results due to a bug?

What happens if the decorated lines become longer than 88 characters (or whatever is the configured Black margin)? I suppose that's ok because the comment instructs Black to ignore those lines and pass them through as such.

Handling of empty lines seems to be asymmetrical in your implementation – decorating them is probably supposed to be special cased as well?

What happens inside multi-line strings?

What happens if I modify only some lines in a multi-line expression which doesn't already conform to Black formatting rules? For example if this is the old revision:

call_func(first_arg=1,
    second_arg = 2,
    third_arg="three"
)

and this is my new revision:

call_func(first_arg=1,
    second_arg = 2,
    third_arg=3
)

(so only the third_arg= line changed)

Would the whole function call still be reformatted by Black, or only the line I modified? According to your "After" example, the latter seems true. Which one would be desirable in your opinion?

Could you approach replace the current difflib-chunk-applying approach completely?

Could we avoid the # fmt:skip variants limitation by appending something unique as another comment? Would Black still recognize its own skip directive?

@akaihola akaihola self-requested a review September 4, 2022 19:01
@akaihola akaihola added the enhancement New feature or request label Sep 4, 2022
@akaihola akaihola added this to the 1.6.0 milestone Sep 4, 2022
@wkentaro
Copy link
Author

wkentaro commented Sep 5, 2022

What happens if the decorated lines become longer than 88 characters (or whatever is the configured Black margin)? I suppose that's ok because the comment instructs Black to ignore those lines and pass them through as such.

Yes, that's going to be ok.


Handling of empty lines seems to be asymmetrical in your implementation – decorating them is probably supposed to be special cased as well?

When there is a line --# fmt: skip (with 2 spaces), Black reformats it to # fmt: skip (no spaces), that's why we need to have an asymmetric de-decoration. Somehow we need to fix along with removing difflib as described below.


What happens inside multi-line strings?

In this case, Black ignores # fmt:skip decoration, and the decoration # fmt:skip is treated as a comment so will affect the result.

image

If we apply black with 2 times, it gives an expected result.

image

UPDATE: if we don't change the line of multi-line string, Black raises error, so this needs to be fixed.


Would the whole function call still be reformatted by Black, or only the line I modified? According to your "After" example, the latter seems true. Which one would be desirable in your opinion?

In this particular case, the Black won't reformat anything as there is going to be ) # fmt: skip, and it cancels the whole reformat of the function call. This is probably the big drawback of this approach.

In my particular use case (a codebase of several people changing), I prefer the more conservative result since I can still reformat lines if I need it by black --code "<lines extracted by editor>" (I use vim and its visual selection). Reformatting again is easier than reverting a reformat.


Could you approach replace the current difflib-chunk-applying approach completely?

I just found an edge case by trying this. Without difflib, it creates an indented line like below:

image

this is because # fmt:skip will be formatted as --# fmt:skip and the trailing 2 spaces cannot be removed with the current algorithm.


Could we avoid the # fmt:skip variants limitation by appending something unique as another comment? Would Black still recognize its own skip directive?

Yes, it seems possible by changing both FMT_SKIP and FMT_PASS.

@akaihola
Copy link
Owner

akaihola commented Sep 8, 2022

What happens inside multi-line strings?

In this case, Black ignores # fmt:skip decoration,

Your example had a concatenation of single-line strings split on multiple lines.

What I meant was a triple-quoted multi-line string like e.g.

"""first line
second line
third line"""

@akaihola
Copy link
Owner

akaihola commented Sep 8, 2022

I prefer the more conservative result [...] Reformatting again is easier than reverting a reformat.

This seems to be a matter of preference. For me it's the opposite – I want the code base to be marching steadily towards complete Blackification, and if this sometimes means that a couple of neighboring unmodified statements are reformatted as well, that's a reasonable trade-off.

This is what I attempted to solve in #221. I hoped to be able to extract Black's reformatted output in chunks corresponding to expressions which are parenthetically balanced and cover a sequence of complete lines of code. If it could also tell which original lines were reformatted, that set of information could replace the use of difflib altogether. Unfortunately this approach didn't really work out (see discussion).

@akaihola akaihola added help wanted Extra attention is needed question Further information is requested maybe invalid? Can't reproduce, or seems already fixed, or need more information labels Sep 17, 2022
@akaihola akaihola modified the milestones: 1.6.0, 1.7.0 Sep 17, 2022
@akaihola akaihola modified the milestones: 1.7.0, 1.8.0 Jan 2, 2023
@akaihola
Copy link
Owner

akaihola commented Jan 2, 2023

I'm postponing to consider this for 1.8.0. There are other features lined up for 1.7.0 and I prefer to not delay it further.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request help wanted Extra attention is needed maybe invalid? Can't reproduce, or seems already fixed, or need more information question Further information is requested
Projects
Development

Successfully merging this pull request may close these issues.

Darker changes lines when the previous lines got changed
2 participants