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

Preserve multiline aspect of a code chunk. #1476

Closed
chebee7i opened this issue Jun 3, 2020 · 5 comments
Closed

Preserve multiline aspect of a code chunk. #1476

chebee7i opened this issue Jun 3, 2020 · 5 comments
Labels
T: enhancement New feature or request

Comments

@chebee7i
Copy link

chebee7i commented Jun 3, 2020

If I have broken up a line of code that happens to fit within the line length limit, then black will reformat it into just one line. For example,

# in:
j = [
    1,
    2,
    3,
]

# out:
j = [1, 2, 3]

While I could prevent this by using fmt: off and fmt: on around the affected lines, this can be quite invasive and litters the code, especially if you have many similar declarations within a module and you just want consistency of style (e.g. all declarations are multiline, even if they are short).

So the only option is to disable black formatting for much larger code segements, which has obvious downsides like not reformating:

j = [1,
     2,
     3]

and not fixing any other formatting issues.

Might it be possible to tell black that we want it to preserve the multi-line aspect of code? That is, fix the other issues, but do not reformat it into just one line.

@chebee7i chebee7i added the T: enhancement New feature or request label Jun 3, 2020
@ichard26
Copy link
Collaborator

ichard26 commented Jun 3, 2020

The "magic trailing comma" should keep that collection exploded.

Early versions of Black used to ruthlessly collapse those into one line (it fits!). Now, you can communicate that you don't want that by putting a trailing comma in the collection yourself. When you do, Black will know to always explode your collection into one item per line.

That seems like a bug to me. What version of Black are you running? Here's my output on master:

(black) richard-26@ubuntu-laptop:~/programming$ cat test.py

test = [
    1,
    2,
    3,
]


(black) richard-26@ubuntu-laptop:~/programming$ black test.py
reformatted test.py
All done! ✨ 🍰 ✨
1 file reformatted.
(black) richard-26@ubuntu-laptop:~/programming$ cat test.py
test = [
    1,
    2,
    3,
]

@trevorbaca
Copy link

Hi @ichard26 is the magic trailing comma working yet for function and method calls? That's the one remaining thing that's preventing me from blacking 100% of my repositories. I cloned and installed the main Black repo today, but it looks like function-embedded magic commas are still forcibly conjoined:

$ black --version
black, version 19.10b1.dev114+gfcf9796

$ cat test.py
def foo(x, y):
    return x + y

foo(
    "Here is some text",
    " and even more text.",
)

$ black test.py
reformatted test.py
All done! ✨ 🍰 ✨
1 file reformatted.

$ cat test.py
def foo(x, y):
    return x + y


foo(
    "Here is some text", " and even more text.",
)

@chebee7i
Copy link
Author

chebee7i commented Jun 3, 2020

Aha, I didn't realize this was a new feature. As of 19.3b0 it was still imploding. Per @trevorbaca, the latest release does seem pretty good, except that it doesn't work for function calls and function definitions. Also, in Python 2, it doesn't work if you have **kwargs (since you can't put a trailing comma after it in 2.x).

Here is how it looks on the latest stable:

$ black --version                                                                    
black, version 19.10b0                                                               

$ cat zzz.py                                                                         
x = [                                                                                
    1,                                                                               
    2,                                                                               
    3,                                                                               
]                                                                                    
                                                                                     
                                                                                     
def f(                                                                               
    a=1,                                                                             
    b=2,                                                                             
    c=3,                                                                             
):                                                                                   
    pass                                                                             
                                                                                     
                                                                                     
f(                                                                                   
    a=1,                                                                             
    b=2,                                                                             
    c=3,                                                                             
)                                                                                    
                                                                                     
                                                                                     
def g(                                                                               
    a=1,                                                                             
    b=2,                                                                             
    c=3,                                                                             
    **kwargs                                                                         
):                                                                                   
    pass                                                                             
                                                                                     
                                                                                     
y = {                                                                                
    'a': 1,                                                                          
    'b': 2,                                                                          
}                                                                                    
                                                                                     
                                                                                     
z = dict(                                                                            
    a=1,                                                                             
    b=2,                                                                             
    c=3,                                                                             
)                                                                                    

$ black zzz.py                                                                       
reformatted zzz.py                                                                   
All done! ✨ 🍰 ✨                                                                   
1 file reformatted.                                                                  

$ cat zzz.py                                                                         
x = [                                                                                
    1,                                                                               
    2,                                                                               
    3,                                                                               
]                                                                                    
                                                                                     
                                                                                     
def f(                                                                               
    a=1, b=2, c=3,                                                                   
):                                                                                   
    pass                                                                             
                                                                                     
                                                                                     
f(                                                                                   
    a=1, b=2, c=3,                                                                   
)                                                                                    
                                                                                     
                                                                                     
def g(a=1, b=2, c=3, **kwargs):                                                      
    pass                                                                             
                                                                                     
                                                                                     
y = {                                                                                
    'a': 1,                                                                          
    'b': 2,                                                                          
}                                                                                    
                                                                                     
                                                                                     
z = dict(a=1, b=2, c=3,)                                                             

@ichard26
Copy link
Collaborator

ichard26 commented Jun 3, 2020

@trevorbaca, @chebee7i

Both of those are known bugs.

Regarding the trailing comma bug within function calls, I think that's similar to these issues:
#1433
#1169
Although those ones are about collections within a function call.

Regarding the trailing comma even after *, *args, and **kwargs (when Black was told to stay <Python3.5 compatible), there are:
#1356
#1463

Yeah, our issue tracker could do with a good cleanup, there are quite a few duplicates :-)

EDIT: Also the "magic trailing comma" doesn't work on nested collections.

@chebee7i
Copy link
Author

Closing this as a duplicate of #1433 and #1288

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
T: enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

3 participants