Repository: timothycrosley/isort
Pull request #944 (2019-05-09 05:41:01)

 keep-direct-and-as only inserts direct import if it was present in the original file
This will fix issue #735 where the --keep-direct-and-as option would add a straight import, even if it wasn't in the original file.
This also fixes issue #606 (using the -k option).
It also seems to be one step closer on #908 but I wasn't concentrating on that issue.

In addition, this change allows the same object to be imported as multiple aliases; which, I agree, is poor style, but removing those aliases causes real crashes. It should probably be up to some other linter to shame the programmer about the double reference.


Patch:
diff --git a/.travis.yml b/.travis.yml
index 28ee6346..47670293 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -10,6 +10,8 @@ matrix:
     - env: TOXENV=isort-check
     - env: TOXENV=lint
     - env: TOXENV=mypy
+    - python: 3.4
+      env: TOXENV=py34-coverage
     - python: 3.5
       env: TOXENV=py35-coverage
     - python: 3.6
diff --git a/README.rst b/README.rst
index 1f644c11..9c5a5794 100644
--- a/README.rst
+++ b/README.rst
@@ -31,7 +31,7 @@ isort your python imports for you so you don't have to.
 
 isort is a Python utility / library to sort imports alphabetically, and automatically separated into sections.
 It provides a command line utility, Python library and `plugins for various editors <https://github.com/timothycrosley/isort/wiki/isort-Plugins>`_ to quickly sort all your imports.
-It requires Python 3.5+ to run but supports formatting Python 2 code too.
+It requires Python 3.4+ to run but supports formatting Python 2 code too.
 
 .. image:: https://raw.github.com/timothycrosley/isort/develop/example.gif
    :alt: Example Usage
diff --git a/appveyor.yml b/appveyor.yml
index 9c743c61..df16a10a 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -10,6 +10,7 @@ environment:
     - TOXENV: "isort-check"
     - TOXENV: "lint"
     - TOXENV: "mypy"
+    - TOXENV: "py34-coverage"
     - TOXENV: "py35-coverage"
     - TOXENV: "py36-coverage"
     - TOXENV: "py37-coverage"
diff --git a/isort/isort.py b/isort/isort.py
index f000494c..21fca23e 100644
--- a/isort/isort.py
+++ b/isort/isort.py
@@ -27,7 +27,7 @@ OTHER DEALINGS IN THE SOFTWARE.
 import copy
 import itertools
 import re
-from collections import OrderedDict, namedtuple
+from collections import OrderedDict, defaultdict, namedtuple
 from typing import TYPE_CHECKING, Any, Dict, Iterable, List, Mapping, Optional, Sequence, Tuple
 
 from isort import utils
@@ -76,7 +76,7 @@ class _SortImports(object):
         self.out_lines = []  # type: List[str]
         self.comments = {'from': {}, 'straight': {}, 'nested': {}, 'above': {'straight': {}, 'from': {}}}  # type: CommentsDict
         self.imports = OrderedDict()  # type: OrderedDict[str, Dict[str, Any]]
-        self.as_map = {}  # type: Dict[str, str]
+        self.as_map = defaultdict(list)  # type: Dict[str, List[str]]
 
         section_names = self.config['sections']
         self.sections = namedtuple('Sections', section_names)(*[name for name in section_names])  # type: Any
@@ -264,18 +264,20 @@ class _SortImports(object):
             if module in self.remove_imports:
                 continue
 
+            import_definition = []
             if module in self.as_map:
-                import_definition = ''
-                if self.config['keep_direct_and_as_imports']:
-                    import_definition = "import {0}\n".format(module)
-                import_definition += "import {0} as {1}".format(module, self.as_map[module])
+                if self.config['keep_direct_and_as_imports'] and self.imports[section]['straight'][module]:
+                    import_definition.append("import {0}".format(module))
+                import_definition.extend("import {0} as {1}".format(module, as_import)
+                                         for as_import in self.as_map[module])
             else:
-                import_definition = "import {0}".format(module)
+                import_definition.append("import {0}".format(module))
 
             comments_above = self.comments['above']['straight'].pop(module, None)
             if comments_above:
                 section_output.extend(comments_above)
-            section_output.append(self._add_comments(self.comments['straight'].get(module), import_definition))
+            section_output.extend(self._add_comments(self.comments['straight'].get(module), idef)
+                                  for idef in import_definition)
 
     def _add_from_imports(self, from_modules: Iterable[str], section: str, section_output: List[str], ignore_case: bool) -> None:
         for module in from_modules:
@@ -292,14 +294,22 @@ class _SortImports(object):
 
             sub_modules = ['{0}.{1}'.format(module, from_import) for from_import in from_imports]
             as_imports = {
-                from_import: "{0} as {1}".format(from_import, self.as_map[sub_module])
+                from_import: ["{0} as {1}".format(from_import, as_module)
+                              for as_module in self.as_map[sub_module]]
                 for from_import, sub_module in zip(from_imports, sub_modules)
                 if sub_module in self.as_map
             }
             if self.config['combine_as_imports'] and not ("*" in from_imports and self.config['combine_star']):
+                if not self.config['no_inline_sort']:
+                    for as_import in as_imports:
+                        as_imports[as_import] = nsorted(as_imports[as_import])
                 for from_import in copy.copy(from_imports):
                     if from_import in as_imports:
-                        from_imports[from_imports.index(from_import)] = as_imports.pop(from_import)
+                        idx = from_imports.index(from_import)
+                        if self.config['keep_direct_and_as_imports'] and self.imports[section]['from'][module][from_import]:
+                            from_imports[(idx+1):(idx+1)] = as_imports.pop(from_import)
+                        else:
+                            from_imports[idx:(idx+1)] = as_imports.pop(from_import)
 
             while from_imports:
                 comments = self.comments['from'].pop(module, ())
@@ -310,29 +320,35 @@ class _SortImports(object):
                     import_statements = []
                     while from_imports:
                         from_import = from_imports.pop(0)
-                        if from_import in as_imports:
-                            from_comments = self.comments['straight'].get('{}.{}'.format(module, from_import))
-                            import_statements.append(self._add_comments(from_comments,
-                                                     self._wrap(import_start + as_imports[from_import])))
-                            continue
                         single_import_line = self._add_comments(comments, import_start + from_import)
                         comment = self.comments['nested'].get(module, {}).pop(from_import, None)
                         if comment:
                             single_import_line += "{0} {1}".format(comments and ";" or self.config['comment_prefix'],
                                                                    comment)
-                        import_statements.append(self._wrap(single_import_line))
+                        if from_import in as_imports:
+                            if self.config['keep_direct_and_as_imports'] and self.imports[section]['from'][module][from_import]:
+                                import_statements.append(self._wrap(single_import_line))
+                            from_comments = self.comments['straight'].get('{}.{}'.format(module, from_import))
+                            import_statements.extend(self._add_comments(from_comments,
+                                                     self._wrap(import_start + as_import))
+                                                     for as_import in nsorted(as_imports[from_import]))
+                        else:
+                            import_statements.append(self._wrap(single_import_line))
                         comments = None
                     import_statement = self.line_separator.join(import_statements)
                 else:
                     while from_imports and from_imports[0] in as_imports:
                         from_import = from_imports.pop(0)
+                        as_imports[from_import] = nsorted(as_imports[from_import])
                         from_comments = self.comments['straight'].get('{}.{}'.format(module, from_import))
                         above_comments = self.comments['above']['from'].pop(module, None)
                         if above_comments:
                             section_output.extend(above_comments)
 
-                        section_output.append(self._add_comments(from_comments,
-                                                                 self._wrap(import_start + as_imports[from_import])))
+                        if self.config['keep_direct_and_as_imports'] and self.imports[section]['from'][module][from_import]:
+                            section_output.append(self._add_comments(from_comments, self._wrap(import_start + from_import)))
+                        section_output.extend(self._add_comments(from_comments, self._wrap(import_start + as_import))
+                                              for as_import in as_imports[from_import])
 
                     star_import = False
                     if "*" in from_imports:
@@ -342,7 +358,7 @@ class _SortImports(object):
                         comments = None
 
                     for from_import in copy.copy(from_imports):
-                        if from_import in as_imports:
+                        if from_import in as_imports and not self.config['keep_direct_and_as_imports']:
                             continue
                         comment = self.comments['nested'].get(module, {}).pop(from_import, None)
                         if comment:
@@ -357,7 +373,10 @@ class _SortImports(object):
                             comments = None
 
                     from_import_section = []
-                    while from_imports and from_imports[0] not in as_imports:
+                    while from_imports and (from_imports[0] not in as_imports or
+                            (self.config['keep_direct_and_as_imports'] and
+                             self.config['combine_as_imports'] and
+                             self.imports[section]['from'][module][from_import])):
                         from_import_section.append(from_imports.pop(0))
                     if star_import:
                         import_statement = import_start + (", ").join(from_import_section)
@@ -876,15 +895,17 @@ class _SortImports(object):
 
                 imports = [item.replace("{|", "{ ").replace("|}", " }") for item in
                            self._strip_syntax(import_string).split()]
+                straight_import = True
                 if "as" in imports and (imports.index('as') + 1) < len(imports):
+                    straight_import = False
                     while "as" in imports:
                         index = imports.index('as')
                         if import_type == "from":
                             module = imports[0] + "." + imports[index - 1]
-                            self.as_map[module] = imports[index + 1]
+                            self.as_map[module].append(imports[index + 1])
                         else:
                             module = imports[index - 1]
-                            self.as_map[module] = imports[index + 1]
+                            self.as_map[module].append(imports[index + 1])
                         if not self.config['combine_as_imports']:
                             self.comments['straight'][module] = comments
                             comments = []
@@ -921,8 +942,10 @@ class _SortImports(object):
                             self.import_index -= len(self.comments['above']['from'].get(import_from, []))
 
                     if import_from not in root:
-                        root[import_from] = OrderedDict()
-                    root[import_from].update((module, None) for module in imports)
+                        root[import_from] = OrderedDict((module, straight_import) for module in imports)
+                    else:
+                        root[import_from].update((module, straight_import | root[import_from].get(module, False))
+                                                 for module in imports)
                 else:
                     for module in imports:
                         if comments:
@@ -950,4 +973,5 @@ class _SortImports(object):
                                 "WARNING: could not place module {0} of line {1} --"
                                 " Do you need to define a default section?".format(import_from, line)
                             )
-                        self.imports[placed_module][import_type][module] = None
+                        straight_import |= self.imports[placed_module][import_type].get(module, False)
+                        self.imports[placed_module][import_type][module] = straight_import
diff --git a/setup.py b/setup.py
index fb5599fd..d93e3d3b 100755
--- a/setup.py
+++ b/setup.py
@@ -27,7 +27,7 @@ setup(name='isort',
           'requirements': ['pipreqs', 'pip-api'],
           'xdg_home': ['appdirs>=1.4.0'],
       },
-      python_requires=">=3.5",
+      python_requires=">=3.4",
       keywords='Refactor, Python, Python3, Refactoring, Imports, Sort, Clean',
       classifiers=['Development Status :: 6 - Mature',
                    'Intended Audience :: Developers',
@@ -36,6 +36,7 @@ setup(name='isort',
                    'License :: OSI Approved :: MIT License',
                    'Programming Language :: Python',
                    'Programming Language :: Python :: 3',
+                   'Programming Language :: Python :: 3.4',
                    'Programming Language :: Python :: 3.5',
                    'Programming Language :: Python :: 3.6',
                    'Programming Language :: Python :: 3.7',
diff --git a/tox.ini b/tox.ini
index 903e9458..0b157187 100644
--- a/tox.ini
+++ b/tox.ini
@@ -4,7 +4,7 @@ envlist =
     isort-check,
     lint,
     mypy,
-    py{35,36,37,py3}
+    py{34,35,36,37,py3}
 
 [testenv]
 deps =


Test patch:
diff --git a/test_isort.py b/test_isort.py
index cd353ef9..6a48bf9e 100644
--- a/test_isort.py
+++ b/test_isort.py
@@ -2848,6 +2848,261 @@ def test_unwrap_issue_762():
     assert SortImports(file_contents=test_input).output == 'from os.path import join, split\n'
 
 
+def test_multiple_as_imports():
+    test_input = ('from a import b as b\n'
+                  'from a import b as bb\n'
+                  'from a import b as bb_\n')
+    test_output = SortImports(file_contents=test_input).output
+    assert test_output == test_input
+    test_output = SortImports(file_contents=test_input, combine_as_imports=True).output
+    assert test_output == 'from a import b as b, b as bb, b as bb_\n'
+    test_output = SortImports(file_contents=test_input, keep_direct_and_as_imports=True).output
+    assert test_output == test_input
+    test_output = SortImports(file_contents=test_input, combine_as_imports=True, keep_direct_and_as_imports=True).output
+    assert test_output == 'from a import b as b, b as bb, b as bb_\n'
+
+    test_input = ('from a import b\n'
+                  'from a import b as b\n'
+                  'from a import b as bb\n'
+                  'from a import b as bb_\n')
+    test_output = SortImports(file_contents=test_input).output
+    assert test_output == 'from a import b as b\nfrom a import b as bb\nfrom a import b as bb_\n'
+    test_output = SortImports(file_contents=test_input, combine_as_imports=True).output
+    assert test_output == 'from a import b as b, b as bb, b as bb_\n'
+    test_output = SortImports(file_contents=test_input, keep_direct_and_as_imports=True).output
+    assert test_output == test_input
+    test_output = SortImports(file_contents=test_input, combine_as_imports=True, keep_direct_and_as_imports=True).output
+    assert test_output == 'from a import b, b as b, b as bb, b as bb_\n'
+
+    test_input = ('from a import b as e\n'
+                  'from a import b as c\n'
+                  'from a import b\n'
+                  'from a import b as f\n')
+    test_output = SortImports(file_contents=test_input).output
+    assert test_output == 'from a import b as c\nfrom a import b as e\nfrom a import b as f\n'
+    test_output = SortImports(file_contents=test_input, combine_as_imports=True).output
+    assert test_output == 'from a import b as c, b as e, b as f\n'
+    test_output = SortImports(file_contents=test_input, keep_direct_and_as_imports=True).output
+    assert test_output == 'from a import b\nfrom a import b as c\nfrom a import b as e\nfrom a import b as f\n'
+    test_output = SortImports(file_contents=test_input, no_inline_sort=True).output
+    assert test_output == 'from a import b as c\nfrom a import b as e\nfrom a import b as f\n'
+    test_output = SortImports(file_contents=test_input, keep_direct_and_as_imports=True, no_inline_sort=True).output
+    assert test_output == 'from a import b\nfrom a import b as c\nfrom a import b as e\nfrom a import b as f\n'
+    test_output = SortImports(file_contents=test_input, combine_as_imports=True, keep_direct_and_as_imports=True).output
+    assert test_output == 'from a import b, b as c, b as e, b as f\n'
+    test_output = SortImports(file_contents=test_input, combine_as_imports=True, no_inline_sort=True).output
+    assert test_output == 'from a import b as e, b as c, b as f\n'
+    test_output = SortImports(file_contents=test_input, combine_as_imports=True, keep_direct_and_as_imports=True, no_inline_sort=True).output
+    assert test_output == 'from a import b, b as e, b as c, b as f\n'
+
+    test_input = ('import a as a\n'
+                  'import a as aa\n'
+                  'import a as aa_\n')
+    test_output = SortImports(file_contents=test_input).output
+    assert test_output == test_input
+    test_output = SortImports(file_contents=test_input, combine_as_imports=True, keep_direct_and_as_imports=True).output
+    assert test_output == test_input
+
+    test_input = ('import a\n'
+                  'import a as a\n'
+                  'import a as aa\n'
+                  'import a as aa_\n')
+    test_output = SortImports(file_contents=test_input).output
+    assert test_output == 'import a as a\nimport a as aa\nimport a as aa_\n'
+    test_output = SortImports(file_contents=test_input, combine_as_imports=True, keep_direct_and_as_imports=True).output
+    assert test_output == test_input
+
+
+def test_all_imports_from_single_module():
+    test_input = ('import a\n'
+                  'from a import *\n'
+                  'from a import b as d\n'
+                  'from a import z, x, y\n'
+                  'from a import b\n'
+                  'from a import w, i as j\n'
+                  'from a import b as c, g as h\n'
+                  'from a import e as f\n')
+    test_output = SortImports(file_contents=test_input, combine_star=False, combine_as_imports=False,
+                              keep_direct_and_as_imports=False, force_single_line=False, no_inline_sort=False).output
+    assert test_output == ('import a\n'
+                           'from a import *\n'
+                           'from a import b as c\n'
+                           'from a import b as d\n'
+                           'from a import e as f\n'
+                           'from a import g as h\n'
+                           'from a import i as j\n'
+                           'from a import w, x, y, z\n')
+    test_output = SortImports(file_contents=test_input, combine_star=True, combine_as_imports=False,
+                              keep_direct_and_as_imports=False, force_single_line=False, no_inline_sort=False).output
+    assert test_output == 'import a\nfrom a import *\n'
+    test_output = SortImports(file_contents=test_input, combine_star=False, combine_as_imports=True,
+                              keep_direct_and_as_imports=False, force_single_line=False, no_inline_sort=False).output
+    assert test_output == ('import a\n'
+                           'from a import *\n'
+                           'from a import b as c, b as d, e as f, g as h, i as j, w, x, y, z\n')
+    test_output = SortImports(file_contents=test_input, combine_star=False, combine_as_imports=False,
+                              keep_direct_and_as_imports=True, force_single_line=False, no_inline_sort=False).output
+    assert test_output == ('import a\n'
+                           'from a import *\n'
+                           'from a import b\n'
+                           'from a import b as c\n'
+                           'from a import b as d\n'
+                           'from a import e as f\n'
+                           'from a import g as h\n'
+                           'from a import i as j\n'
+                           'from a import w, x, y, z\n')
+    test_output = SortImports(file_contents=test_input, combine_star=False, combine_as_imports=False,
+                              keep_direct_and_as_imports=False, force_single_line=True, no_inline_sort=False).output
+    assert test_output == ('import a\n'
+                           'from a import *\n'
+                           'from a import b as c\n'
+                           'from a import b as d\n'
+                           'from a import e as f\n'
+                           'from a import g as h\n'
+                           'from a import i as j\n'
+                           'from a import w\n'
+                           'from a import x\n'
+                           'from a import y\n'
+                           'from a import z\n')
+    test_output = SortImports(file_contents=test_input, combine_star=False, combine_as_imports=False,
+                              keep_direct_and_as_imports=False, force_single_line=False, no_inline_sort=True).output
+    assert test_output == ('import a\n'
+                           'from a import *\n'
+                           'from a import b as c\n'
+                           'from a import b as d\n'
+                           'from a import z, x, y, w\n'
+                           'from a import i as j\n'
+                           'from a import g as h\n'
+                           'from a import e as f\n')
+    test_output = SortImports(file_contents=test_input, combine_star=True, combine_as_imports=True,
+                              keep_direct_and_as_imports=False, force_single_line=False, no_inline_sort=False).output
+    assert test_output == 'import a\nfrom a import *\n'
+    test_output = SortImports(file_contents=test_input, combine_star=True, combine_as_imports=False,
+                              keep_direct_and_as_imports=True, force_single_line=False, no_inline_sort=False).output
+    assert test_output == 'import a\nfrom a import *\n'
+    test_output = SortImports(file_contents=test_input, combine_star=True, combine_as_imports=False,
+                              keep_direct_and_as_imports=False, force_single_line=True, no_inline_sort=False).output
+    assert test_output == 'import a\nfrom a import *\n'
+    test_output = SortImports(file_contents=test_input, combine_star=True, combine_as_imports=False,
+                              keep_direct_and_as_imports=False, force_single_line=False, no_inline_sort=True).output
+    assert test_output == 'import a\nfrom a import *\n'
+    test_output = SortImports(file_contents=test_input, combine_star=False, combine_as_imports=True,
+                              keep_direct_and_as_imports=True, force_single_line=False, no_inline_sort=False).output
+    assert test_output == ('import a\n'
+                           'from a import *\n'
+                           'from a import b, b as c, b as d, e as f, g as h, i as j, w, x, y, z\n')
+    test_output = SortImports(file_contents=test_input, combine_star=False, combine_as_imports=True,
+                              keep_direct_and_as_imports=False, force_single_line=True, no_inline_sort=False).output
+    assert test_output == ('import a\n'
+                           'from a import *\n'
+                           'from a import b as c\n'
+                           'from a import b as d\n'
+                           'from a import e as f\n'
+                           'from a import g as h\n'
+                           'from a import i as j\n'
+                           'from a import w\n'
+                           'from a import x\n'
+                           'from a import y\n'
+                           'from a import z\n')
+    test_output = SortImports(file_contents=test_input, combine_star=False, combine_as_imports=True,
+                              keep_direct_and_as_imports=False, force_single_line=False, no_inline_sort=True).output
+    assert test_output == ('import a\n'
+                           'from a import *\n'
+                           'from a import b as d, b as c, z, x, y, w, i as j, g as h, e as f\n')
+    test_output = SortImports(file_contents=test_input, combine_star=False, combine_as_imports=False,
+                              keep_direct_and_as_imports=True, force_single_line=True, no_inline_sort=False).output
+    assert test_output == ('import a\n'
+                           'from a import *\n'
+                           'from a import b\n'
+                           'from a import b as c\n'
+                           'from a import b as d\n'
+                           'from a import e as f\n'
+                           'from a import g as h\n'
+                           'from a import i as j\n'
+                           'from a import w\n'
+                           'from a import x\n'
+                           'from a import y\n'
+                           'from a import z\n')
+    test_output = SortImports(file_contents=test_input, combine_star=False, combine_as_imports=False,
+                              keep_direct_and_as_imports=True, force_single_line=False, no_inline_sort=True).output
+    assert test_output == ('import a\n'
+                           'from a import *\n'
+                           'from a import b\n'
+                           'from a import b as c\n'
+                           'from a import b as d\n'
+                           'from a import z, x, y, w\n'
+                           'from a import i as j\n'
+                           'from a import g as h\n'
+                           'from a import e as f\n')
+    test_output = SortImports(file_contents=test_input, combine_star=False, combine_as_imports=False,
+                              keep_direct_and_as_imports=False, force_single_line=True, no_inline_sort=True).output
+    assert test_output == ('import a\n'
+                           'from a import *\n'
+                           'from a import b as c\n'
+                           'from a import b as d\n'
+                           'from a import e as f\n'
+                           'from a import g as h\n'
+                           'from a import i as j\n'
+                           'from a import w\n'
+                           'from a import x\n'
+                           'from a import y\n'
+                           'from a import z\n')
+    test_output = SortImports(file_contents=test_input, combine_star=True, combine_as_imports=True,
+                              keep_direct_and_as_imports=True, force_single_line=False, no_inline_sort=False).output
+    assert test_output == 'import a\nfrom a import *\n'
+    test_output = SortImports(file_contents=test_input, combine_star=True, combine_as_imports=True,
+                              keep_direct_and_as_imports=False, force_single_line=True, no_inline_sort=False).output
+    assert test_output == 'import a\nfrom a import *\n'
+    test_output = SortImports(file_contents=test_input, combine_star=True, combine_as_imports=True,
+                              keep_direct_and_as_imports=False, force_single_line=False, no_inline_sort=True).output
+    assert test_output == 'import a\nfrom a import *\n'
+    test_output = SortImports(file_contents=test_input, combine_star=True, combine_as_imports=False,
+                              keep_direct_and_as_imports=True, force_single_line=True, no_inline_sort=False).output
+    assert test_output == 'import a\nfrom a import *\n'
+    test_output = SortImports(file_contents=test_input, combine_star=True, combine_as_imports=False,
+                              keep_direct_and_as_imports=True, force_single_line=False, no_inline_sort=True).output
+    assert test_output == 'import a\nfrom a import *\n'
+    test_output = SortImports(file_contents=test_input, combine_star=True, combine_as_imports=False,
+                              keep_direct_and_as_imports=False, force_single_line=True, no_inline_sort=True).output
+    assert test_output == 'import a\nfrom a import *\n'
+    test_output = SortImports(file_contents=test_input, combine_star=False, combine_as_imports=True,
+                              keep_direct_and_as_imports=True, force_single_line=True, no_inline_sort=False).output
+    assert test_output == ('import a\n'
+                           'from a import *\n'
+                           'from a import b\n'
+                           'from a import b as c\n'
+                           'from a import b as d\n'
+                           'from a import e as f\n'
+                           'from a import g as h\n'
+                           'from a import i as j\n'
+                           'from a import w\n'
+                           'from a import x\n'
+                           'from a import y\n'
+                           'from a import z\n')
+    test_output = SortImports(file_contents=test_input, combine_star=False, combine_as_imports=True,
+                              keep_direct_and_as_imports=True, force_single_line=False, no_inline_sort=True).output
+    assert test_output == ('import a\n'
+                           'from a import *\n'
+                           'from a import b, b as d, b as c, z, x, y, w, i as j, g as h, e as f\n')
+    test_output = SortImports(file_contents=test_input, combine_star=False, combine_as_imports=False,
+                              keep_direct_and_as_imports=True, force_single_line=True, no_inline_sort=True).output
+    assert test_output == ('import a\n'
+                           'from a import *\n'
+                           'from a import b\n'
+                           'from a import b as c\n'
+                           'from a import b as d\n'
+                           'from a import e as f\n'
+                           'from a import g as h\n'
+                           'from a import i as j\n'
+                           'from a import w\n'
+                           'from a import x\n'
+                           'from a import y\n'
+                           'from a import z\n')
+    test_output = SortImports(file_contents=test_input, combine_star=True, combine_as_imports=True,
+                              keep_direct_and_as_imports=True, force_single_line=True, no_inline_sort=False).output
+    assert test_output == 'import a\nfrom a import *\n'
+
+
 def test_noqa_issue_679():
     # Test to ensure that NOQA notation is being observed as expected
     test_input = ('import os\n'