Repository: timothycrosley/isort
Pull request #610 (2017-11-06 21:40:07)

merge only neighbour sections in case of enabled no_lines_before option
Hi!

I've found an unexpected behavior in earlier introduced `no-lines-before` option. Suppose we have STDLIB and local imports. We obviously won't want to merge them into one group. So I think it has much more sense to merge only neighbor sections, which might be configured via `sections` or `forced_separate` options


Patch:
diff --git a/isort/isort.py b/isort/isort.py
index 24e53d60..99c3b23d 100644
--- a/isort/isort.py
+++ b/isort/isort.py
@@ -547,6 +547,7 @@ class SortImports(object):
             sections = ('no_sections', )
 
         output = []
+        prev_section_has_imports = False
         for section in sections:
             straight_modules = self.imports[section]['straight']
             straight_modules = nsorted(straight_modules, key=lambda key: self._module_key(key, self.config))
@@ -590,10 +591,11 @@ class SortImports(object):
                     section_comment = "# {0}".format(section_title)
                     if section_comment not in self.out_lines[0:1] and section_comment not in self.in_lines[0:1]:
                         section_output.insert(0, section_comment)
-                if section_name in self.config['no_lines_before']:
+                if prev_section_has_imports and section_name in self.config['no_lines_before']:
                     while output and output[-1].strip() == '':
                         output.pop()
                 output += section_output + ([''] * self.config['lines_between_sections'])
+            prev_section_has_imports = bool(section_output)
         while output and output[-1].strip() == '':
             output.pop()
         while output and output[0].strip() == '':


Test patch:
diff --git a/test_isort.py b/test_isort.py
index 6dbb7c2b..5db6c69e 100644
--- a/test_isort.py
+++ b/test_isort.py
@@ -2200,7 +2200,7 @@ def test_ensure_as_imports_sort_correctly_within_from_imports_issue_590():
                   'from os import pathsep as separator\n')
     assert SortImports(file_contents=test_input, force_single_line=True).output == test_input
 
-    
+
 def test_ensure_line_endings_are_preserved_issue_493():
     """Test to ensure line endings are not converted"""
     test_input = ('from os import defpath\r\n'
@@ -2213,7 +2213,7 @@ def test_ensure_line_endings_are_preserved_issue_493():
                   'from os import pathsep as separator\n')
     assert SortImports(file_contents=test_input).output == test_input
 
-    
+
 def test_not_splitted_sections():
     whiteline = '\n'
     stdlib_section = 'import unittest\n'
@@ -2231,11 +2231,17 @@ def test_not_splitted_sections():
                stdlib_section + whiteline + firstparty_section + local_section +
                whiteline + statement
            )
-    assert SortImports(file_contents=test_input, no_lines_before=['FIRSTPARTY']).output == \
-           (
-               stdlib_section + firstparty_section + whiteline + local_section +
-               whiteline + statement
-           )
-    assert SortImports(file_contents=test_input, no_lines_before=['FIRSTPARTY', 'LOCALFOLDER']).output == \
-           (stdlib_section + firstparty_section + local_section + whiteline + statement)
-
+    # by default STDLIB and FIRSTPARTY sections are split by THIRDPARTY section,
+    # so don't merge them if THIRDPARTY imports aren't exist
+    assert SortImports(file_contents=test_input, no_lines_before=['FIRSTPARTY']).output == test_input
+    # in case when THIRDPARTY section is excluded from sections list, it's ok to merge STDLIB and FIRSTPARTY
+    assert SortImports(
+        file_contents=test_input,
+        sections=['STDLIB', 'FIRSTPARTY', 'LOCALFOLDER'],
+        no_lines_before=['FIRSTPARTY'],
+    ).output == (
+        stdlib_section + firstparty_section + whiteline + local_section +
+        whiteline + statement
+    )
+    # it doesn't change output, because stdlib packages don't have any whitelines before them
+    assert SortImports(file_contents=test_input, no_lines_before=['STDLIB']).output == test_input