grantjenks / blue

The slightly less uncompromising Python code formatter.
https://blue.readthedocs.io/
Other
395 stars 21 forks source link

Don't split a series of semicolon terminated statements #61

Open rhettinger opened 2 years ago

rhettinger commented 2 years ago

People put in semicolons intentionally. It is almost never an accidental occurrence. We should respect the user's explicit intention.

In debugging code, there are natural logical pairings that are almost always done together. This facilitates easily inserting, moving, copying, and removal of the logical pair (which the user thinks of a single discrete step rather than a series of steps):

import pdb; pdb.pm()

For timing code, the start/action/end/report cycle form a natural, logical grouping that leaves the timed steps in their logical, consecutive sequence:

start = time(); step1(x); end = time(); print(end - start)
start = time(); step2(y); end = time(); print(end - start)

In Lib/cgitb.py, these statements naturally occur as a pair:

import cgitb; cgitb.enable()

In Tools/scripts/var_accessbenchmark.py, the existing code looks pleasing to the eye and makes it easy to see how many times v_local is being called:

def read_local(trials=trials):
    v_local = 1
    for t in trials:
        v_local;    v_local;    v_local;    v_local;    v_local
        v_local;    v_local;    v_local;    v_local;    v_local
        v_local;    v_local;    v_local;    v_local;    v_local
        v_local;    v_local;    v_local;    v_local;    v_local
        v_local;    v_local;    v_local;    v_local;    v_local

In Lib/idlelib/multicall.py, we see a typical use in grouping constants. These could be split on separate lines but it distracts from the overall flow of reading the module and makes it more difficult to relate back to the source of this information. I could go either way on this one but think it is best to respect the author's intention:

# the event type constants, which define the meaning of mc_type
MC_KEYPRESS=0; MC_KEYRELEASE=1; MC_BUTTONPRESS=2; MC_BUTTONRELEASE=3;
MC_ACTIVATE=4; MC_CIRCULATE=5; MC_COLORMAP=6; MC_CONFIGURE=7;
MC_DEACTIVATE=8; MC_DESTROY=9; MC_ENTER=10; MC_EXPOSE=11; MC_FOCUSIN=12;
MC_FOCUSOUT=13; MC_GRAVITY=14; MC_LEAVE=15; MC_MAP=16; MC_MOTION=17;
MC_MOUSEWHEEL=18; MC_PROPERTY=19; MC_REPARENT=20; MC_UNMAP=21; MC_VISIBILITY=22;

# the modifier state constants, which define the meaning of mc_state
MC_SHIFT = 1<<0; MC_CONTROL = 1<<2; MC_ALT = 1<<3; MC_META = 1<<5
MC_OPTION = 1<<6; MC_COMMAND = 1<<7

In Lib/mailcap.py, we see this pair several times. It is a common pattern for consuming a value and advancing an index. The reason the author put them on the same line is that it makes it easy to see verify that every consumed value also advances the index. It would be a mistake to do the first without the second. So, the formatter should respect the logical grouping of statements:

c = field[i:i+1]; i = i+1