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

Black should have an opinion about all blank lines #1219

Closed
john-bodley opened this issue Jan 4, 2020 · 6 comments
Closed

Black should have an opinion about all blank lines #1219

john-bodley opened this issue Jan 4, 2020 · 6 comments
Labels
T: enhancement New feature or request

Comments

@john-bodley
Copy link

john-bodley commented Jan 4, 2020

Is your feature request related to a problem? Please describe.

There are a number of open issues related to handling blank lines (#932, #355, etc.) but I was wondering whether Black should have an opinion about all blank lines to further ensure code consistency and remove unnecessary style nits.

In addition to existing issues in relation to blank lines around comments, docstrings, etc. I wonder if Black should also be opinionated about whether blank lines should be present either preceding, within, or succeeding:

  • if statements
  • loops
  • try/except blocks
  • multiline statements
  • return statements
  • inline functions
  • etc.

Describe the solution you'd like

Personally for if statements, loops, try/except blocks, and multiline statements I prefer having a blank line preceding and succeeding the statement if the indentation level is the same, i.e.,

try:
    x = int(input())
    x2 = x ** 2
    
    y = a_multiline_statement(
        x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x
    )

    if x % 2 == 0:
        print("even")
    else:
        print("odd")

    for i in range(x):
        for j in range(x):
            if i != j:
                print(i * j)
except ValueError as e:
    print(str(e))

Describe alternatives you've considered
None.

@john-bodley john-bodley added the T: enhancement New feature or request label Jan 4, 2020
@ftruzzi
Copy link

ftruzzi commented Jan 8, 2020

+1, I also think this should be supported.

I like the formatting solution proposed by @john-bodley, but I like to always leave an empty line after return statements to mentally break the code flow while reading, e.g.:

if x%2 == 0:
  # do stuff
  return x

elif x%3 ==0:
  # do more stuff
  # stuff stuff
  return x+1

else:
  return x+2

or

def f(a):
  try:
    # do stuff
  except KeyError:
    return {}
  
  return a 

I understand if some consider this spurious whitespace though. What do others think?

EDIT: control flow whitespace was already addressed here #90

@ptsl
Copy link

ptsl commented Jan 9, 2020

+1. While space should be consistent as well.

@ambv
Copy link
Collaborator

ambv commented Mar 3, 2020

Black used to initially have a strong opinion about all blank lines. My initial thinking was that if you need to split your functions into sections... you want more functions. But this argument proved to be extremely unpopular so I backed out of it.

And @ftruzzi, if you look at the history of the project, Black initially did put blank lines after control flow statements (return, raise, continue, and break). I like this myself but unfortunately there were annoying edge cases with it so it was not a good rule to enforce every time.

So in general, I think we won't be doing what this request is suggesting. There are related bugs (like handling double blank lines in functions that are preceeded by a comment line; or standardizing on no blank lines after docstrings) that we might address. But we sadly cannot enforce any blanket usage of blank lines.

@gabroo
Copy link

gabroo commented Jun 17, 2020

@ambv what about blank lines between code blocks?

for instance

1  def sphere_vol(r):                     
2      """                                
3      Volume of a sphere                 
4      """                                
5      return (4 / 3) * math.pi * (r ** 3)
6                                       
7                                        
8  def sphere_sa(r):                      
9      """                                
10     Surface area of a sphere           
11     """                                
12     return 4 * math.pi * (r ** 2)      

either line 6 or 7 should be removed

I suppose black won't treat docstrings as blocks but at least for functions/import blocks?

@JelleZijlstra
Copy link
Collaborator

Black's style is to put two lines between functions.

@john-bodley
Copy link
Author

john-bodley commented Aug 14, 2021

@ambv and @cooperlees and I was wondering whether there have been any change of thinking regarding this issue? I work in a number of large code bases (both internal and open source including https://github.com/apache/superset) and having Black being more opinionated would be tremendous in my opinion to better ensure consistency.

The part I find hard to fathom is, in my opinion, the main reason for the overwhelming success of Black compared to other auto-formatters is—per the tag line—that it is the uncompromising code formatter, yet it seems to turn a blind eye to blank lines which if leveraged correctly can greatly impact the readability of the code (see #1364) and thus likely should be taken into account when formatting.

Note I think it's worthwhile pointing out that Black still is somewhat opinionated about blank lines, i.e., it enforces a blank line after an import/from statement, blank lines between class/function declarations, etc.

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

6 participants