Repository: timothycrosley/isort
Pull request #982 (2019-08-14 12:11:24)

Simplify subprocess use with high level run API
Per the Python docs, subprocess.run() is the preferred interface for
running subprocess and replaces the older API (such as
subprocess.check_output())

https://docs.python.org/3/library/subprocess.html

> The recommended approach to invoking subprocesses is to use the run()
> function for all use cases it can handle. For more advanced use cases,
> the underlying Popen interface can be used directly.
>
>
> The run() function was added in Python 3.5; if you need to retain
> compatibility with older versions, see the Older high-level API
> section.

Allows for:

- Return a str from get_output() to decode once instead of every line of
  the result.

- Pass command arguments as a list of strings to ensure no possibility
  for unescaped shell injection.

codecov-io: # [Codecov](https://codecov.io/gh/timothycrosley/isort/pull/982?src=pr&el=h1) Report
> Merging [#982](https://codecov.io/gh/timothycrosley/isort/pull/982?src=pr&el=desc) into [develop](https://codecov.io/gh/timothycrosley/isort/commit/cec922efa020adeeba3196a48327295e08e66acb?src=pr&el=desc) will **not change** coverage.
> The diff coverage is `100%`.


```diff
@@           Coverage Diff            @@
##           develop     #982   +/-   ##
========================================
  Coverage    89.69%   89.69%           
========================================
  Files           10       10           
  Lines         2631     2631           
  Branches       453      453           
========================================
  Hits          2360     2360           
  Misses         184      184           
  Partials        87       87
```


Patch:
diff --git a/ACKNOWLEDGEMENTS.md b/ACKNOWLEDGEMENTS.md
index 971ee83c..c51a2604 100644
--- a/ACKNOWLEDGEMENTS.md
+++ b/ACKNOWLEDGEMENTS.md
@@ -81,6 +81,8 @@ Code Contributors
 - Madison Caldwell (@madirey)
 - Matt Yule-Bennett (@mattbennett)
 - Jaswanth Kumar (@jaswanth098)
+- Dario Navin (@Zarathustra2)
+
 
 Documenters
 ===================
diff --git a/isort/compat.py b/isort/compat.py
index 2d6317ba..9f618636 100644
--- a/isort/compat.py
+++ b/isort/compat.py
@@ -95,7 +95,8 @@ class SortImports(object):
             absolute_file_path = resolve(file_path)
             if check_skip:
                 if run_path and run_path in absolute_file_path.parents:
-                    file_name = os.path.relpath(absolute_file_path, run_path)
+                    # TODO: Drop str() when isort is Python 3.6+.
+                    file_name = os.path.relpath(str(absolute_file_path), run_path)
                 else:
                     file_name = str(absolute_file_path)
                     run_path = ''
diff --git a/isort/finders.py b/isort/finders.py
index c7e24b62..2605d743 100644
--- a/isort/finders.py
+++ b/isort/finders.py
@@ -57,12 +57,14 @@ class ForcedSeparateFinder(BaseFinder):
 
             if fnmatch(module_name, path_glob) or fnmatch(module_name, '.' + path_glob):
                 return forced_separate
+        return None
 
 
 class LocalFinder(BaseFinder):
     def find(self, module_name: str) -> Optional[str]:
         if module_name.startswith("."):
             return self.sections.LOCALFOLDER
+        return None
 
 
 class KnownPatternFinder(BaseFinder):
@@ -106,6 +108,7 @@ class KnownPatternFinder(BaseFinder):
             for pattern, placement in self.known_patterns:
                 if pattern.match(module_name_to_check):
                     return placement
+        return None
 
 
 class PathFinder(BaseFinder):
@@ -176,6 +179,7 @@ class PathFinder(BaseFinder):
                 if os.path.normcase(prefix).startswith(self.stdlib_lib_prefix):
                     return self.sections.STDLIB
                 return self.config['default_section']
+        return None
 
 
 class ReqsBaseFinder(BaseFinder):
@@ -269,6 +273,7 @@ class ReqsBaseFinder(BaseFinder):
         for name in self.names:
             if module_name == name:
                 return self.sections.THIRDPARTY
+        return None
 
 
 class RequirementsFinder(ReqsBaseFinder):
@@ -390,3 +395,4 @@ class FindersManager(object):
                                                                                                        module_name))
             if section is not None:
                 return section
+        return None
diff --git a/isort/hooks.py b/isort/hooks.py
index a14493f0..2e075270 100644
--- a/isort/hooks.py
+++ b/isort/hooks.py
@@ -28,17 +28,18 @@ from typing import List
 from isort import SortImports
 
 
-def get_output(command: str) -> bytes:
+def get_output(command: List[str]) -> str:
     """
     Run a command and return raw output
 
     :param str command: the command to run
     :returns: the stdout output of the command
     """
-    return subprocess.check_output(command.split())
+    result = subprocess.run(command, stdout=subprocess.PIPE, check=True)
+    return result.stdout.decode()
 
 
-def get_lines(command: str) -> List[str]:
+def get_lines(command: List[str]) -> List[str]:
     """
     Run a command and return lines of output
 
@@ -46,7 +47,7 @@ def get_lines(command: str) -> List[str]:
     :returns: list of whitespace-stripped lines output by command
     """
     stdout = get_output(command)
-    return [line.strip().decode() for line in stdout.splitlines()]
+    return [line.strip() for line in stdout.splitlines()]
 
 
 def git_hook(strict=False, modify=False):
@@ -64,19 +65,19 @@ def git_hook(strict=False, modify=False):
     """
 
     # Get list of files modified and staged
-    diff_cmd = "git diff-index --cached --name-only --diff-filter=ACMRTUXB HEAD"
+    diff_cmd = ["git", "diff-index", "--cached", "--name-only", "--diff-filter=ACMRTUXB HEAD"]
     files_modified = get_lines(diff_cmd)
 
     errors = 0
     for filename in files_modified:
         if filename.endswith('.py'):
             # Get the staged contents of the file
-            staged_cmd = "git show :%s" % filename
+            staged_cmd = ["git", "show", ":%s" % filename]
             staged_contents = get_output(staged_cmd)
 
             sort = SortImports(
                 file_path=filename,
-                file_contents=staged_contents.decode(),
+                file_contents=staged_contents,
                 check=True
             )
 
@@ -85,7 +86,7 @@ def git_hook(strict=False, modify=False):
                 if modify:
                     SortImports(
                         file_path=filename,
-                        file_contents=staged_contents.decode(),
+                        file_contents=staged_contents,
                         check=False,
                     )
 
diff --git a/isort/isort.py b/isort/isort.py
index c5342d39..93d42a6d 100644
--- a/isort/isort.py
+++ b/isort/isort.py
@@ -159,6 +159,7 @@ class _SortImports(object):
             return "straight"
         elif line.startswith('from '):
             return "from"
+        return None
 
     def _at_end(self) -> bool:
         """returns True if we are at the end of the file."""
diff --git a/isort/main.py b/isort/main.py
index e603b419..64bf2f47 100644
--- a/isort/main.py
+++ b/isort/main.py
@@ -298,6 +298,9 @@ def parse_args(argv: Optional[Sequence[str]] = None) -> Dict[str, Any]:
     parser.add_argument('--filter-files', dest='filter_files', action='store_true',
                         help='Tells isort to filter files even when they are explicitly passed in as part of the command')
     parser.add_argument('files', nargs='*', help='One or more Python source files that need their imports sorted.')
+    parser.add_argument('-py', '--python-version', action='store', dest='py_version',
+                        help='Tells isort to sort the standard library based on the python version. '
+                             'Default is the version of the running interpreter, for instance: -py 3, -py 2.7')
 
     arguments = {key: value for key, value in vars(parser.parse_args(argv)).items() if value}
     if 'dont_order_by_type' in arguments:
diff --git a/isort/settings.py b/isort/settings.py
index b4d3911a..bf156ef3 100644
--- a/isort/settings.py
+++ b/isort/settings.py
@@ -28,12 +28,15 @@ import fnmatch
 import os
 import posixpath
 import re
+import sys
 import warnings
 from distutils.util import strtobool
 from functools import lru_cache
 from pathlib import Path
-from typing import Any, Callable, Dict, Iterable, List, Mapping, MutableMapping, Union
+from typing import Any, Callable, Dict, Iterable, List, Mapping, MutableMapping, Optional, Union
 
+from .stdlibs.py_three import standard_library_3
+from .stdlibs.py_two import standard_library_2
 from .utils import difference, union
 
 try:
@@ -72,6 +75,48 @@ class WrapModes(enum.Enum):
         return getattr(WrapModes, str(value), None) or WrapModes(int(value))
 
 
+def _get_default(py_version: Optional[str]) -> dict:
+    """
+    Returns the correct standard library based on either the passed py_version flag or the python interpreter
+    Additionaly users have the option to pass all as value instead of an
+    version. As an result code will be checked against both standard libraries - python2 & python3
+
+    See Issue 889 and 778 for more information
+    """
+
+    if py_version is None:
+        major, minor = sys.version_info[0:2]
+    elif py_version is not "all":
+        minor = 0
+
+        # we have a minor
+        if "." in py_version:
+            # we do not care about patches just major and minor
+            splits = py_version.split(".")[0:2]
+            major = int(splits[0])
+            minor = int(splits[1])
+        else:
+            major = int(py_version)
+
+    _default = default.copy()
+
+    if py_version is "all":
+        standard_library = list(set(standard_library_3 + standard_library_2))
+    elif major == 3:
+        standard_library = standard_library_3
+    elif major == 2 and minor == 7:
+        standard_library = standard_library_2
+    else:
+        raise ValueError(
+            "The python version %s is not supported. "
+            "You can set a python version with the -py or --python-version flag " % py_version
+        )
+
+    _default['known_standard_library'] = standard_library
+
+    return _default
+
+
 # Note that none of these lists must be complete as they are simply fallbacks for when included auto-detection fails.
 default = {'force_to_top': [],
            'skip': [],
@@ -82,51 +127,6 @@ default = {'force_to_top': [],
            'sections': DEFAULT_SECTIONS,
            'no_sections': False,
            'known_future_library': ['__future__'],
-           'known_standard_library': ['AL', 'BaseHTTPServer', 'Bastion', 'CGIHTTPServer', 'Carbon', 'ColorPicker',
-                                      'ConfigParser', 'Cookie', 'DEVICE', 'DocXMLRPCServer', 'EasyDialogs', 'FL',
-                                      'FrameWork', 'GL', 'HTMLParser', 'MacOS', 'MimeWriter', 'MiniAEFrame', 'Nav',
-                                      'PixMapWrapper', 'Queue', 'SUNAUDIODEV', 'ScrolledText', 'SimpleHTTPServer',
-                                      'SimpleXMLRPCServer', 'SocketServer', 'StringIO', 'Tix', 'Tkinter', 'UserDict',
-                                      'UserList', 'UserString', 'W', '__builtin__', 'abc', 'aepack', 'aetools',
-                                      'aetypes', 'aifc', 'al', 'anydbm', 'applesingle', 'argparse', 'array', 'ast',
-                                      'asynchat', 'asyncio', 'asyncore', 'atexit', 'audioop', 'autoGIL', 'base64',
-                                      'bdb', 'binascii', 'binhex', 'bisect', 'bsddb', 'buildtools', 'builtins',
-                                      'bz2', 'cPickle', 'cProfile', 'cStringIO', 'calendar', 'cd', 'cfmfile', 'cgi',
-                                      'cgitb', 'chunk', 'cmath', 'cmd', 'code', 'codecs', 'codeop', 'collections',
-                                      'colorsys', 'commands', 'compileall', 'compiler', 'concurrent', 'configparser',
-                                      'contextlib', 'contextvars', 'cookielib', 'copy', 'copy_reg', 'copyreg', 'crypt', 'csv',
-                                      'ctypes', 'curses', 'dataclasses', 'datetime', 'dbhash', 'dbm', 'decimal', 'difflib',
-                                      'dircache', 'dis', 'distutils', 'dl', 'doctest', 'dumbdbm', 'dummy_thread',
-                                      'dummy_threading', 'email', 'encodings', 'ensurepip', 'enum', 'errno',
-                                      'exceptions', 'faulthandler', 'fcntl', 'filecmp', 'fileinput', 'findertools',
-                                      'fl', 'flp', 'fm', 'fnmatch', 'formatter', 'fpectl', 'fpformat', 'fractions',
-                                      'ftplib', 'functools', 'future_builtins', 'gc', 'gdbm', 'gensuitemodule',
-                                      'getopt', 'getpass', 'gettext', 'gl', 'glob', 'grp', 'gzip', 'hashlib',
-                                      'heapq', 'hmac', 'hotshot', 'html', 'htmlentitydefs', 'htmllib', 'http',
-                                      'httplib', 'ic', 'icopen', 'imageop', 'imaplib', 'imgfile', 'imghdr', 'imp',
-                                      'importlib', 'imputil', 'inspect', 'io', 'ipaddress', 'itertools', 'jpeg',
-                                      'json', 'keyword', 'lib2to3', 'linecache', 'locale', 'logging', 'lzma',
-                                      'macerrors', 'macostools', 'macpath', 'macresource', 'mailbox', 'mailcap',
-                                      'marshal', 'math', 'md5', 'mhlib', 'mimetools', 'mimetypes', 'mimify', 'mmap',
-                                      'modulefinder', 'msilib', 'msvcrt', 'multifile', 'multiprocessing', 'mutex',
-                                      'netrc', 'new', 'nis', 'nntplib', 'numbers', 'operator', 'optparse', 'os',
-                                      'ossaudiodev', 'parser', 'pathlib', 'pdb', 'pickle', 'pickletools', 'pipes',
-                                      'pkgutil', 'platform', 'plistlib', 'popen2', 'poplib', 'posix', 'posixfile',
-                                      'pprint', 'profile', 'pstats', 'pty', 'pwd', 'py_compile', 'pyclbr', 'pydoc',
-                                      'queue', 'quopri', 'random', 're', 'readline', 'reprlib', 'resource', 'rexec',
-                                      'rfc822', 'rlcompleter', 'robotparser', 'runpy', 'sched', 'secrets', 'select',
-                                      'selectors', 'sets', 'sgmllib', 'sha', 'shelve', 'shlex', 'shutil', 'signal',
-                                      'site', 'sitecustomize', 'smtpd', 'smtplib', 'sndhdr', 'socket', 'socketserver',
-                                      'spwd', 'sqlite3', 'ssl', 'stat', 'statistics', 'statvfs', 'string', 'stringprep',
-                                      'struct', 'subprocess', 'sunau', 'sunaudiodev', 'symbol', 'symtable', 'sys',
-                                      'sysconfig', 'syslog', 'tabnanny', 'tarfile', 'telnetlib', 'tempfile', 'termios',
-                                      'test', 'textwrap', 'this', 'thread', 'threading', 'time', 'timeit', 'tkinter',
-                                      'token', 'tokenize', 'trace', 'traceback', 'tracemalloc', 'ttk', 'tty', 'turtle',
-                                      'turtledemo', 'types', 'typing', 'unicodedata', 'unittest', 'urllib', 'urllib2',
-                                      'urlparse', 'usercustomize', 'uu', 'uuid', 'venv', 'videoreader',
-                                      'warnings', 'wave', 'weakref', 'webbrowser', 'whichdb', 'winreg', 'winsound',
-                                      'wsgiref', 'xdrlib', 'xml', 'xmlrpc', 'xmlrpclib', 'zipapp', 'zipfile',
-                                      'zipimport', 'zlib'],
            'known_third_party': ['google.appengine.api'],
            'known_first_party': [],
            'multi_line_output': WrapModes.GRID,
@@ -173,8 +173,8 @@ default = {'force_to_top': [],
 
 
 @lru_cache()
-def from_path(path: Union[str, Path]) -> Dict[str, Any]:
-    computed_settings = default.copy()
+def from_path(path: Union[str, Path], py_version: Optional[str] = None) -> Dict[str, Any]:
+    computed_settings = _get_default(py_version)
     isort_defaults = ['~/.isort.cfg']
     if appdirs:
         isort_defaults = [appdirs.user_config_dir('isort.cfg')] + isort_defaults
@@ -191,7 +191,8 @@ def from_path(path: Union[str, Path]) -> Dict[str, Any]:
 
 
 def prepare_config(settings_path: Path, **setting_overrides: Any) -> Dict[str, Any]:
-    config = from_path(settings_path).copy()
+    py_version = setting_overrides.pop("py_version", None)
+    config = from_path(settings_path, py_version).copy()
     for key, value in setting_overrides.items():
         access_key = key.replace('not_', '').lower()
         # The sections config needs to retain order and can't be converted to a set.
diff --git a/isort/stdlibs/__init__.py b/isort/stdlibs/__init__.py
new file mode 100644
index 00000000..e69de29b
diff --git a/isort/stdlibs/py_three.py b/isort/stdlibs/py_three.py
new file mode 100644
index 00000000..744e19d1
--- /dev/null
+++ b/isort/stdlibs/py_three.py
@@ -0,0 +1,52 @@
+"""
+File contains the standard library of python3
+
+If in any minor the standard library changes, a new list should be
+created and the names adjusted
+"""
+
+standard_library_3 = ['AL', 'BaseHTTPServer', 'Bastion', 'CGIHTTPServer', 'Carbon', 'ColorPicker',
+                      'ConfigParser', 'Cookie', 'DEVICE', 'DocXMLRPCServer', 'EasyDialogs', 'FL',
+                      'FrameWork', 'GL', 'HTMLParser', 'MacOS', 'MimeWriter', 'MiniAEFrame', 'Nav',
+                      'PixMapWrapper', 'Queue', 'SUNAUDIODEV', 'ScrolledText', 'SimpleHTTPServer',
+                      'SimpleXMLRPCServer', 'SocketServer', 'StringIO', 'Tix', 'Tkinter', 'UserDict',
+                      'UserList', 'UserString', 'W', '__builtin__', 'abc', 'aepack', 'aetools',
+                      'aetypes', 'aifc', 'al', 'anydbm', 'applesingle', 'argparse', 'array', 'ast',
+                      'asynchat', 'asyncio', 'asyncore', 'atexit', 'audioop', 'autoGIL', 'base64',
+                      'bdb', 'binascii', 'binhex', 'bisect', 'bsddb', 'buildtools', 'builtins',
+                      'bz2', 'cPickle', 'cProfile', 'cStringIO', 'calendar', 'cd', 'cfmfile', 'cgi',
+                      'cgitb', 'chunk', 'cmath', 'cmd', 'code', 'codecs', 'codeop', 'collections',
+                      'colorsys', 'commands', 'compileall', 'compiler', 'concurrent', 'configparser',
+                      'contextlib', 'contextvars', 'cookielib', 'copy', 'copy_reg', 'copyreg', 'crypt', 'csv',
+                      'ctypes', 'curses', 'dataclasses', 'datetime', 'dbhash', 'dbm', 'decimal', 'difflib',
+                      'dircache', 'dis', 'distutils', 'dl', 'doctest', 'dumbdbm', 'dummy_thread',
+                      'dummy_threading', 'email', 'encodings', 'ensurepip', 'enum', 'errno',
+                      'exceptions', 'faulthandler', 'fcntl', 'filecmp', 'fileinput', 'findertools',
+                      'fl', 'flp', 'fm', 'fnmatch', 'formatter', 'fpectl', 'fpformat', 'fractions',
+                      'ftplib', 'functools', 'future_builtins', 'gc', 'gdbm', 'gensuitemodule',
+                      'getopt', 'getpass', 'gettext', 'gl', 'glob', 'grp', 'gzip', 'hashlib',
+                      'heapq', 'hmac', 'hotshot', 'html', 'htmlentitydefs', 'htmllib', 'http',
+                      'httplib', 'ic', 'icopen', 'imageop', 'imaplib', 'imgfile', 'imghdr', 'imp',
+                      'importlib', 'imputil', 'inspect', 'io', 'ipaddress', 'itertools', 'jpeg',
+                      'json', 'keyword', 'lib2to3', 'linecache', 'locale', 'logging', 'lzma',
+                      'macerrors', 'macostools', 'macpath', 'macresource', 'mailbox', 'mailcap',
+                      'marshal', 'math', 'md5', 'mhlib', 'mimetools', 'mimetypes', 'mimify', 'mmap',
+                      'modulefinder', 'msilib', 'msvcrt', 'multifile', 'multiprocessing', 'mutex',
+                      'netrc', 'new', 'nis', 'nntplib', 'numbers', 'operator', 'optparse', 'os',
+                      'ossaudiodev', 'parser', 'pathlib', 'pdb', 'pickle', 'pickletools', 'pipes',
+                      'pkgutil', 'platform', 'plistlib', 'popen2', 'poplib', 'posix', 'posixfile',
+                      'pprint', 'profile', 'pstats', 'pty', 'pwd', 'py_compile', 'pyclbr', 'pydoc',
+                      'queue', 'quopri', 'random', 're', 'readline', 'reprlib', 'resource', 'rexec',
+                      'rfc822', 'rlcompleter', 'robotparser', 'runpy', 'sched', 'secrets', 'select',
+                      'selectors', 'sets', 'sgmllib', 'sha', 'shelve', 'shlex', 'shutil', 'signal',
+                      'site', 'sitecustomize', 'smtpd', 'smtplib', 'sndhdr', 'socket', 'socketserver',
+                      'spwd', 'sqlite3', 'ssl', 'stat', 'statistics', 'statvfs', 'string', 'stringprep',
+                      'struct', 'subprocess', 'sunau', 'sunaudiodev', 'symbol', 'symtable', 'sys',
+                      'sysconfig', 'syslog', 'tabnanny', 'tarfile', 'telnetlib', 'tempfile', 'termios',
+                      'test', 'textwrap', 'this', 'thread', 'threading', 'time', 'timeit', 'tkinter',
+                      'token', 'tokenize', 'trace', 'traceback', 'tracemalloc', 'ttk', 'tty', 'turtle',
+                      'turtledemo', 'types', 'typing', 'unicodedata', 'unittest', 'urllib', 'urllib2',
+                      'urlparse', 'usercustomize', 'uu', 'uuid', 'venv', 'videoreader',
+                      'warnings', 'wave', 'weakref', 'webbrowser', 'whichdb', 'winreg', 'winsound',
+                      'wsgiref', 'xdrlib', 'xml', 'xmlrpc', 'xmlrpclib', 'zipapp', 'zipfile',
+                      'zipimport', 'zlib']
diff --git a/isort/stdlibs/py_two.py b/isort/stdlibs/py_two.py
new file mode 100644
index 00000000..f00c6f3e
--- /dev/null
+++ b/isort/stdlibs/py_two.py
@@ -0,0 +1,49 @@
+"""
+File contains the standard library of python 2.7
+"""
+
+standard_library_2 = ['AL', 'BaseHTTPServer', 'Bastion', 'CGIHTTPServer', 'Carbon', 'ColorPicker',
+                      'ConfigParser', 'Cookie', 'DEVICE', 'DocXMLRPCServer', 'EasyDialogs', 'FL',
+                      'FrameWork', 'GL', 'HTMLParser', 'MacOS', 'MimeWriter', 'MiniAEFrame', 'Nav',
+                      'PixMapWrapper', 'Queue', 'SUNAUDIODEV', 'ScrolledText', 'SimpleHTTPServer',
+                      'SimpleXMLRPCServer', 'SocketServer', 'StringIO', 'Tix', 'Tkinter', 'UserDict',
+                      'UserList', 'UserString', 'W', '__builtin__', 'abc', 'aepack', 'aetools',
+                      'aetypes', 'aifc', 'al', 'anydbm', 'applesingle', 'argparse', 'array', 'ast',
+                      'asynchat', 'asyncio', 'asyncore', 'atexit', 'audioop', 'autoGIL', 'base64',
+                      'bdb', 'binascii', 'binhex', 'bisect', 'bsddb', 'buildtools', 'builtins',
+                      'bz2', 'cPickle', 'cProfile', 'cStringIO', 'calendar', 'cd', 'cfmfile', 'cgi',
+                      'cgitb', 'chunk', 'cmath', 'cmd', 'code', 'codecs', 'codeop', 'collections',
+                      'colorsys', 'commands', 'compileall', 'compiler', 'concurrent', 'configparser',
+                      'contextlib', 'contextvars', 'cookielib', 'copy', 'copy_reg', 'copyreg', 'crypt', 'csv',
+                      'ctypes', 'curses', 'dataclasses', 'datetime', 'dbhash', 'dbm', 'decimal', 'difflib',
+                      'dircache', 'dis', 'distutils', 'dl', 'doctest', 'dumbdbm', 'dummy_thread',
+                      'dummy_threading', 'email', 'encodings', 'ensurepip', 'enum', 'errno',
+                      'exceptions', 'faulthandler', 'fcntl', 'filecmp', 'fileinput', 'findertools',
+                      'fl', 'flp', 'fm', 'fnmatch', 'formatter', 'fpectl', 'fpformat', 'fractions',
+                      'ftplib', 'functools', 'future_builtins', 'gc', 'gdbm', 'gensuitemodule',
+                      'getopt', 'getpass', 'gettext', 'gl', 'glob', 'grp', 'gzip', 'hashlib',
+                      'heapq', 'hmac', 'hotshot', 'html', 'htmlentitydefs', 'htmllib', 'http',
+                      'httplib', 'ic', 'icopen', 'imageop', 'imaplib', 'imgfile', 'imghdr', 'imp',
+                      'importlib', 'imputil', 'inspect', 'io', 'ipaddress', 'itertools', 'jpeg',
+                      'json', 'keyword', 'lib2to3', 'linecache', 'locale', 'logging', 'lzma',
+                      'macerrors', 'macostools', 'macpath', 'macresource', 'mailbox', 'mailcap',
+                      'marshal', 'math', 'md5', 'mhlib', 'mimetools', 'mimetypes', 'mimify', 'mmap',
+                      'modulefinder', 'msilib', 'msvcrt', 'multifile', 'multiprocessing', 'mutex',
+                      'netrc', 'new', 'nis', 'nntplib', 'numbers', 'operator', 'optparse', 'os',
+                      'ossaudiodev', 'parser', 'pathlib', 'pdb', 'pickle', 'pickletools', 'pipes',
+                      'pkgutil', 'platform', 'plistlib', 'popen2', 'poplib', 'posix', 'posixfile',
+                      'pprint', 'profile', 'pstats', 'pty', 'pwd', 'py_compile', 'pyclbr', 'pydoc',
+                      'queue', 'quopri', 'random', 're', 'readline', 'reprlib', 'resource', 'rexec',
+                      'rfc822', 'rlcompleter', 'robotparser', 'runpy', 'sched', 'secrets', 'select',
+                      'selectors', 'sets', 'sgmllib', 'sha', 'shelve', 'shlex', 'shutil', 'signal',
+                      'site', 'sitecustomize', 'smtpd', 'smtplib', 'sndhdr', 'socket', 'socketserver',
+                      'spwd', 'sqlite3', 'ssl', 'stat', 'statistics', 'statvfs', 'string', 'stringprep',
+                      'struct', 'subprocess', 'sunau', 'sunaudiodev', 'symbol', 'symtable', 'sys',
+                      'sysconfig', 'syslog', 'tabnanny', 'tarfile', 'telnetlib', 'tempfile', 'termios',
+                      'test', 'textwrap', 'this', 'thread', 'threading', 'time', 'timeit', 'tkinter',
+                      'token', 'tokenize', 'trace', 'traceback', 'tracemalloc', 'ttk', 'tty', 'turtle',
+                      'turtledemo', 'types', 'typing', 'unicodedata', 'unittest', 'urllib', 'urllib2',
+                      'urlparse', 'user', 'usercustomize', 'uu', 'uuid', 'venv', 'videoreader',
+                      'warnings', 'wave', 'weakref', 'webbrowser', 'whichdb', 'winreg', 'winsound',
+                      'wsgiref', 'xdrlib', 'xml', 'xmlrpc', 'xmlrpclib', 'zipapp', 'zipfile',
+                      'zipimport', 'zlib']
diff --git a/setup.cfg b/setup.cfg
index 14571a02..f8324a66 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -10,14 +10,11 @@ ignore =
     # W504 line break after binary operator
     W504
 
-[metadata]
-license_file = LICENSE
-
 [mypy]
+python_version = 3.5
 follow_imports = silent
 ignore_missing_imports = True
 strict_optional = True
-warn_no_return = False
 check_untyped_defs = True
 allow_redefinition = True
 
diff --git a/setup.py b/setup.py
index 7ca16da3..f1e0747c 100755
--- a/setup.py
+++ b/setup.py
@@ -1,6 +1,6 @@
 #!/usr/bin/env python3
 
-from setuptools import setup
+from setuptools import find_packages, setup
 
 with open('README.rst') as f:
     readme = f.read()
@@ -20,7 +20,7 @@ setup(name='isort',
         'distutils.commands': ['isort = isort.main:ISortCommand'],
         'pylama.linter': ['isort = isort.pylama_isort:Linter'],
       },
-      packages=['isort'],
+      packages=find_packages(),
       extras_require={
           'pipfile': ['pipreqs', 'requirementslib'],
           'pyproject': ['toml'],


Test patch:
diff --git a/test_isort.py b/test_isort.py
index 86c7d868..ff061da0 100644
--- a/test_isort.py
+++ b/test_isort.py
@@ -24,9 +24,9 @@ import io
 import os
 import os.path
 import posixpath
+import subprocess
 import sys
 import sysconfig
-from subprocess import check_output
 from tempfile import NamedTemporaryFile
 from typing import Any, Dict, List
 
@@ -3230,11 +3230,15 @@ def test_settings_path_skip_issue_909(tmpdir):
     test_run_directory = os.getcwd()
     os.chdir(str(base_dir))
     with pytest.raises(Exception):  # without the settings path provided: the command should not skip & identify errors
-        check_output(['isort', '--check-only'])
-    results = check_output(['isort', '--check-only', '--settings-path=conf/.isort.cfg'])
+        subprocess.run(['isort', '--check-only'], check=True)
+    result = subprocess.run(
+        ['isort', '--check-only', '--settings-path=conf/.isort.cfg'],
+        stdout=subprocess.PIPE,
+        check=True
+    )
     os.chdir(str(test_run_directory))
 
-    assert b'skipped 2' in results.lower()
+    assert b'skipped 2' in result.stdout.lower()
 
 
 def test_skip_paths_issue_938(tmpdir):
@@ -3261,16 +3265,24 @@ def test_skip_paths_issue_938(tmpdir):
 
     test_run_directory = os.getcwd()
     os.chdir(str(base_dir))
-    results = check_output(['isort', 'dont_skip.py', 'migrations/file_glob_skip.py'])
+    result = subprocess.run(
+        ['isort', 'dont_skip.py', 'migrations/file_glob_skip.py'],
+        stdout=subprocess.PIPE,
+        check=True,
+    )
     os.chdir(str(test_run_directory))
 
-    assert b'skipped' not in results.lower()
+    assert b'skipped' not in result.stdout.lower()
 
     os.chdir(str(base_dir))
-    results = check_output(['isort', '--filter-files', '--settings-path=conf/.isort.cfg', 'dont_skip.py', 'migrations/file_glob_skip.py'])
+    result = subprocess.run(
+        ['isort', '--filter-files', '--settings-path=conf/.isort.cfg', 'dont_skip.py', 'migrations/file_glob_skip.py'],
+        stdout=subprocess.PIPE,
+        check=True,
+    )
     os.chdir(str(test_run_directory))
 
-    assert b'skipped 1' in results.lower()
+    assert b'skipped 1' in result.stdout.lower()
 
 
 def test_failing_file_check_916():
@@ -3352,3 +3364,28 @@ def test_pyi_formatting_issue_942(tmpdir):
     source_pyi = tmpdir.join('source.pyi')
     source_pyi.write(test_input)
     assert SortImports(file_path=str(source_pyi)).output.splitlines() == expected_pyi_output
+
+
+def test_python_version():
+    from isort.main import parse_args
+
+    # test that the py_version can be added as flag
+    args = parse_args(['-py=2.7'])
+    assert args["py_version"] == "2.7"
+
+    args = parse_args(['--python-version=3'])
+    assert args["py_version"] == "3"
+
+    test_input = ('import os\n'
+                  '\n'
+                  'import user\n')
+    assert SortImports(file_contents=test_input, py_version="3").output == test_input
+
+    # user is part of the standard library in python 2
+    output_python_2 = ('import os\n'
+                       'import user\n')
+    assert SortImports(file_contents=test_input, py_version="2.7").output == output_python_2
+
+    test_input = ('import os\nimport xml')
+
+    print(SortImports(file_contents=test_input, py_version="all").output )