Split imports like isort

Fixes #127

Partially addresses #152
This commit is contained in:
Łukasz Langa 2018-04-24 13:44:28 -07:00
parent b250aed47b
commit 09f5ee3a19
3 changed files with 50 additions and 0 deletions

View File

@ -176,6 +176,13 @@ between two distinct sections of the code that otherwise share the same
indentation level (like the arguments list and the docstring in the indentation level (like the arguments list and the docstring in the
example above). example above).
If a line of "from" imports cannot fit in the allotted length, it's always split
into one per line. Imports tend to change often and this minimizes diffs, as well
as enables readers of code to easily find which commit introduced a particular
import. This exception also makes *Black* compatible with
[isort](https://pypi.org/p/isort/). Use `multi_line_output=3` and
`include_trailing_comma=True` in your isort config.
### Line length ### Line length
@ -528,6 +535,8 @@ More details can be found in [CONTRIBUTING](CONTRIBUTING.md).
* Black no longer enforces putting empty lines behind control flow statements * Black no longer enforces putting empty lines behind control flow statements
(#90) (#90)
* Black now splits imports like "Mode 3 + trailing comma" of isort (#127)
* fixed comment indentation when a standalone comment closes a block (#16, #32) * fixed comment indentation when a standalone comment closes a block (#16, #32)
* fixed standalone comments receiving extra empty lines if immediately preceding * fixed standalone comments receiving extra empty lines if immediately preceding

View File

@ -1712,6 +1712,8 @@ def split_line(
split_funcs: List[SplitFunc] split_funcs: List[SplitFunc]
if line.is_def: if line.is_def:
split_funcs = [left_hand_split] split_funcs = [left_hand_split]
elif line.is_import:
split_funcs = [explode_split]
elif line.inside_brackets: elif line.inside_brackets:
split_funcs = [delimiter_split, standalone_comment_split, right_hand_split] split_funcs = [delimiter_split, standalone_comment_split, right_hand_split]
else: else:
@ -1978,6 +1980,24 @@ def append_to_line(leaf: Leaf) -> Iterator[Line]:
yield current_line yield current_line
def explode_split(
line: Line, py36: bool = False, omit: Collection[LeafID] = ()
) -> Iterator[Line]:
"""Split by RHS and immediately split contents by a delimiter."""
new_lines = list(right_hand_split(line, py36, omit))
if len(new_lines) != 3:
yield from new_lines
return
yield new_lines[0]
try:
yield from delimiter_split(new_lines[1], py36)
except CannotSplit:
yield new_lines[1]
yield new_lines[2]
def is_import(leaf: Leaf) -> bool: def is_import(leaf: Leaf) -> bool:
"""Return True if the given leaf starts an import statement.""" """Return True if the given leaf starts an import statement."""
p = leaf.parent p = leaf.parent

View File

@ -17,6 +17,10 @@
from ..queues import * from ..queues import *
from ..streams import * from ..streams import *
from some_library import (
Just, Enough, Libraries, To, Fit, In, This, Nice, Split, Which, We, No, Longer, Use
)
from .a.b.c.subprocess import * from .a.b.c.subprocess import *
from . import (tasks) from . import (tasks)
from . import (A, B, C) from . import (A, B, C)
@ -59,6 +63,23 @@
from ..queues import * from ..queues import *
from ..streams import * from ..streams import *
from some_library import (
Just,
Enough,
Libraries,
To,
Fit,
In,
This,
Nice,
Split,
Which,
We,
No,
Longer,
Use,
)
from .a.b.c.subprocess import * from .a.b.c.subprocess import *
from . import tasks from . import tasks
from . import A, B, C from . import A, B, C