Repository: timothycrosley/isort
Pull request #333 (2015-09-16 04:38:58)

Feature/fix issue 328


Patch:
diff --git a/isort/isort.py b/isort/isort.py
index e5f8ed84..4ce3270d 100644
--- a/isort/isort.py
+++ b/isort/isort.py
@@ -133,10 +133,7 @@ class SortImports(object):
         self._first_comment_index_end = -1
         self._parse()
         if self.import_index != -1:
-            if self.config.get('force_alphabetical_sort', False):
-                self._sort_alphabetically()
-            else:
-                self._add_formatted_imports()
+            self._add_formatted_imports()
 
         self.length_change = len(self.out_lines) - self.original_length
         while self.out_lines and self.out_lines[-1].strip() == "":
@@ -451,33 +448,58 @@ class SortImports(object):
         (at the index of the first import) sorted alphabetically and split between groups
 
         """
-        output = []
-        for section in itertools.chain(self.sections, self.config['forced_separate']):
-            straight_modules = list(self.imports[section]['straight'])
-            straight_modules = nsorted(straight_modules, key=lambda key: self._module_key(key, self.config))
-            from_modules = sorted(list(self.imports[section]['from'].keys()))
-            from_modules = nsorted(from_modules, key=lambda key: self._module_key(key, self.config, ))
-
-            section_output = []
-            if self.config.get('from_first', False):
-                self._add_from_imports(from_modules, section, section_output)
-                self._add_straight_imports(straight_modules, section, section_output)
-            else:
-                self._add_straight_imports(straight_modules, section, section_output)
-                self._add_from_imports(from_modules, section, section_output)
-
-            if section_output:
-                section_name = section
-                if section_name in self.place_imports:
-                    self.place_imports[section_name] = section_output
-                    continue
-
-                section_title = self.config.get('import_heading_' + str(section_name).lower(), '')
-                if section_title:
-                    section_comment = "# {0}".format(section_title)
-                    if not section_comment in self.out_lines[0:1]:
-                        section_output.insert(0, section_comment)
-                output += section_output + ['']
+        if self.config.get('force_alphabetical_sort', False):
+            from_output = []
+            straight_output = []
+            for section in itertools.chain(self.sections, self.config['forced_separate']):
+                straight_modules = list(self.imports[section]['straight'])
+                from_modules = list(self.imports[section]['from'].keys())
+
+                self._add_from_imports(from_modules, section, from_output)
+                self._add_straight_imports(straight_modules, section, straight_output)
+
+            new_from_output = []
+            new_straight_output = []
+            for line in from_output:
+                for element in line.split('\n'):
+                    new_from_output.append(element)
+            for line in straight_output:
+                for element in line.split('\n'):
+                    new_straight_output.append(element)
+
+
+            sorted_from = sorted(new_from_output, key=lambda s: s.lower())
+            sorted_straight = sorted(new_straight_output, key=lambda s: s.lower())
+            output = (sorted_from + [''] + sorted_straight) if (sorted_from and sorted_straight) else \
+                     (sorted_from or sorted_straight)
+        else:
+            output = []
+            for section in itertools.chain(self.sections, self.config['forced_separate']):
+                straight_modules = list(self.imports[section]['straight'])
+                straight_modules = nsorted(straight_modules, key=lambda key: self._module_key(key, self.config))
+                from_modules = sorted(list(self.imports[section]['from'].keys()))
+                from_modules = nsorted(from_modules, key=lambda key: self._module_key(key, self.config, ))
+
+                section_output = []
+                if self.config.get('from_first', False):
+                    self._add_from_imports(from_modules, section, section_output)
+                    self._add_straight_imports(straight_modules, section, section_output)
+                else:
+                    self._add_straight_imports(straight_modules, section, section_output)
+                    self._add_from_imports(from_modules, section, section_output)
+
+                if section_output:
+                    section_name = section
+                    if section_name in self.place_imports:
+                        self.place_imports[section_name] = section_output
+                        continue
+
+                    section_title = self.config.get('import_heading_' + str(section_name).lower(), '')
+                    if section_title:
+                        section_comment = "# {0}".format(section_title)
+                        if not section_comment in self.out_lines[0:1]:
+                            section_output.insert(0, section_comment)
+                    output += section_output + ['']
 
         while [character.strip() for character in output[-1:]] == [""]:
             output.pop()
@@ -519,41 +541,6 @@ class SortImports(object):
                         new_out_lines.append("")
             self.out_lines = new_out_lines
 
-    def _sort_alphabetically(self):
-        """Adds the imports back to the file sorted alphabetically."""
-        from_output = []
-        straight_output = []
-        for section in itertools.chain(self.sections, self.config['forced_separate']):
-            straight_modules = list(self.imports[section]['straight'])
-            from_modules = list(self.imports[section]['from'].keys())
-
-            self._add_from_imports(from_modules, section, from_output)
-            self._add_straight_imports(straight_modules, section, straight_output)
-
-        new_from_output = []
-        new_straight_output = []
-        for line in from_output:
-            for element in line.split('\n'):
-                new_from_output.append(element)
-        for line in straight_output:
-            for element in line.split('\n'):
-                new_straight_output.append(element)
-
-
-        sorted_from = sorted(new_from_output, key=lambda s: s.lower())
-        sorted_straight = sorted(new_straight_output, key=lambda s: s.lower())
-        output = sorted_from + ['', ] + sorted_straight
-
-        while [character.strip() for character in output[-1:]] == [""]:
-            output.pop()
-
-        output_at = 0
-        if self.import_index < self.original_length:
-            output_at = self.import_index
-        elif self._first_comment_index_end != -1 and self._first_comment_index_start <= 2:
-            output_at = self._first_comment_index_end
-        self.out_lines[output_at:0] = output
-
     def _output_grid(self, statement, imports, white_space, indent, line_length, comments):
         statement += "(" + imports.pop(0)
         while imports:


Test patch:
diff --git a/test_isort.py b/test_isort.py
index dda9a72f..540ef988 100644
--- a/test_isort.py
+++ b/test_isort.py
@@ -1588,3 +1588,20 @@ def test_sections_parsed_correct():
         assert SortImports(file_contents=test_input, settings_path=tmp_conf_dir).output == correct_output
     finally:
         shutil.rmtree(tmp_conf_dir, ignore_errors=True)
+
+
+def test_alphabetic_sorting_no_newlines():
+    '''Test to ensure that alphabetical sort does not erroneously introduce new lines (issue #328)'''
+    test_input = "import os\n"
+    test_output = SortImports(file_contents=test_input,force_alphabetical_sort=True).output
+    assert test_input == test_output
+
+    test_input = ('from a import b\n'
+                  '\n'
+                  'import os\n'
+                  'import unittest\n'
+                  '\n'
+                  '\n'
+                  'print(1)\n')
+    test_output = SortImports(file_contents=test_input,force_alphabetical_sort=True, lines_after_imports=2).output
+    assert test_input == test_output