Repository: timothycrosley/isort
Pull request #416 (2016-03-30 23:36:32)

Fix single line imports for hanging indents. 
Fix single line imports for hanging indents. 
Changed 1 test for the above.

Fixes:
https://github.com/timothycrosley/isort/issues/365

I added an if on line 429 to say "If line is too long & we have at least 1 import & we are using a hanging indent wrap mode" -> then we format the line. 

It looks ok, but please check it and point out if I have made a mistake. 


Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 9972e04a..335129d8 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -55,6 +55,3 @@ Changelog
 - Fixed stray print statement printing skipped files (issue #411)
 - Added option for forcing imports into a single bucket: `no_sections`
 - Added option for new lines between import types (from, straight): `lines_between_sections`
-
-### 4.2.5
-- Fixed an issue that caused modules to inccorectly be matched as thirdparty when they simply had `src` in the leading path, even if they weren't withing $VIRTUALENV/src #414
diff --git a/isort/__init__.py b/isort/__init__.py
index 082128cd..90757d7d 100644
--- a/isort/__init__.py
+++ b/isort/__init__.py
@@ -25,4 +25,4 @@ from __future__ import absolute_import, division, print_function, unicode_litera
 from . import settings
 from .isort import SortImports
 
-__version__ = "4.2.5"
+__version__ = "4.2.4"
diff --git a/isort/isort.py b/isort/isort.py
index 70954b0f..ca81e576 100644
--- a/isort/isort.py
+++ b/isort/isort.py
@@ -241,20 +241,17 @@ class SortImports(object):
 
         paths = PYTHONPATH
         virtual_env = self.config.get('virtual_env') or os.environ.get('VIRTUAL_ENV')
-        virtual_env_src = False
         if virtual_env:
             paths += [path for path in glob('{0}/lib/python*/site-packages'.format(virtual_env))
                       if path not in paths]
             paths += [path for path in glob('{0}/src/*'.format(virtual_env)) if os.path.isdir(path)]
-            virtual_env_src = '{0}/src/'.format(virtual_env)
 
         for prefix in paths:
             module_path = "/".join((prefix, module_name.replace(".", "/")))
             package_path = "/".join((prefix, module_name.split(".")[0]))
             if (os.path.exists(module_path + ".py") or os.path.exists(module_path + ".so") or
                (os.path.exists(package_path) and os.path.isdir(package_path))):
-                if ('site-packages' in prefix or 'dist-packages' in prefix or
-                    (virtual_env and virtual_env_src in prefix)):
+                if 'site-packages' in prefix or 'dist-packages' in prefix or 'src' in prefix:
                     return self.sections.THIRDPARTY
                 elif 'python2' in prefix.lower() or 'python3' in prefix.lower():
                     return self.sections.STDLIB
@@ -418,10 +415,21 @@ class SortImports(object):
                         import_statement = self._add_comments(comments, import_start + (", ").join(from_imports))
                     if not from_imports:
                         import_statement = ""
-                    if len(from_imports) > 1 and (
-                        len(import_statement) > self.config['line_length']
-                        or self.config.get('force_grid_wrap')
-                    ):
+
+                    do_multiline_reformat = False
+
+                    if self.config.get('force_grid_wrap') and len(from_imports) > 1:
+                        do_multiline_reformat = True
+
+                    if len(import_statement) > self.config['line_length'] and len(from_imports) > 1:
+                        do_multiline_reformat = True
+
+                    # If line too long AND have imports AND we are NOT using GRID or VERTICAL wrap modes
+                    if (len(import_statement) > self.config['line_length'] and len(from_imports) > 0
+                        and self.config.get('multi_line_output', 0) not in (1, 0)):
+                        do_multiline_reformat = True
+
+                    if do_multiline_reformat:
                         output_mode = settings.WrapModes._fields[self.config.get('multi_line_output',
                                                                                     0)].lower()
                         formatter = getattr(self, "_output_" + output_mode, self._output_grid)
@@ -445,7 +453,8 @@ class SortImports(object):
                                 new_import_statement = formatter(import_start, copy.copy(from_imports),
                                                                 dynamic_indent, indent, line_length, comments)
                                 lines = new_import_statement.split("\n")
-                    elif len(import_statement) > self.config['line_length']:
+
+                    if not do_multiline_reformat and len(import_statement) > self.config['line_length']:
                         import_statement = self._wrap(import_statement)
 
                 if import_statement:
@@ -463,6 +472,7 @@ class SortImports(object):
         sort_ignore_case = self.config.get('force_alphabetical_sort_within_sections', False)
         sections = itertools.chain(self.sections, self.config['forced_separate'])
 
+        sections = itertools.chain(self.sections, self.config['forced_separate'])
         if self.config.get('no_sections', False):
             self.imports['no_sections'] = {'straight': [], 'from': {}}
             for section in sections:
diff --git a/setup.py b/setup.py
index c07a2bc7..1397bfeb 100755
--- a/setup.py
+++ b/setup.py
@@ -39,13 +39,13 @@ with open('README.rst', 'r') as f:
    readme = f.read()
 
 setup(name='isort',
-      version='4.2.5',
+      version='4.2.4',
       description='A Python utility / library to sort Python imports.',
       long_description=readme,
       author='Timothy Crosley',
       author_email='timothy.crosley@gmail.com',
       url='https://github.com/timothycrosley/isort',
-      download_url='https://github.com/timothycrosley/isort/archive/4.2.5.tar.gz',
+      download_url='https://github.com/timothycrosley/isort/archive/4.2.4.tar.gz',
       license="MIT",
       entry_points={
         'console_scripts': [


Test patch:
diff --git a/test_isort.py b/test_isort.py
index 8b924fd2..11ea6a18 100644
--- a/test_isort.py
+++ b/test_isort.py
@@ -768,6 +768,7 @@ def test_force_single_line_long_imports():
     assert test_output == ("from veryveryveryveryveryvery import big\n"
                            "from veryveryveryveryveryvery import small  # NOQA\n")
 
+
 def test_titled_imports():
     """Tests setting custom titled/commented import sections."""
     test_input = ("import sys\n"
@@ -1458,15 +1459,14 @@ def test_fcntl():
 
 def test_import_split_is_word_boundary_aware():
     """Test to ensure that isort splits words in a boundry aware mannor"""
-    test_input = ("from mycompany.model.size_value_array_import_func import ("
-                "    get_size_value_array_import_func_jobs,"
-                ")")
+    test_input = ("from mycompany.model.size_value_array_import_func import \\\n"
+                "    get_size_value_array_import_func_jobs")
     test_output = SortImports(file_contents=test_input,
       multi_line_output=WrapModes.VERTICAL_HANGING_INDENT,
       line_length=79).output
-
-    assert test_output == ("from mycompany.model.size_value_array_import_func import \\\n"
-                           "    get_size_value_array_import_func_jobs\n")
+    assert test_output == ("from mycompany.model.size_value_array_import_func import (\n"
+                           "    get_size_value_array_import_func_jobs\n"
+                           ")\n")
 
 
 def test_other_file_encodings():