summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTimothy Crosley <timothy.crosley@gmail.com>2019-03-04 21:19:55 -0800
committerTimothy Crosley <timothy.crosley@gmail.com>2019-03-04 21:19:55 -0800
commit6956e7b4d83c9fd198f78ea2e9c72a41ef7fb602 (patch)
tree2ce4edceeecd906dd8dce64a5b96b1d9471bfa4f
parenta2246c834f2f929099fddc86dfc0c70c1d1c1ba4 (diff)
parent638746f219dbf9f12fdeb783f062c8d8d09c4152 (diff)
downloadisort-6956e7b4d83c9fd198f78ea2e9c72a41ef7fb602.tar.gz
Merge branch 'develop' of https://github.com/timothycrosley/isort into develop
-rw-r--r--.travis.yml8
-rw-r--r--CHANGELOG.md13
-rw-r--r--README.rst3
-rw-r--r--isort/__init__.py2
-rw-r--r--isort/isort.py56
-rw-r--r--isort/main.py8
-rw-r--r--isort/settings.py36
-rw-r--r--isort/utils.py9
-rwxr-xr-xscripts/before_install.sh28
-rwxr-xr-xsetup.py2
10 files changed, 112 insertions, 53 deletions
diff --git a/.travis.yml b/.travis.yml
index 0cd3f4c2..4b6ded30 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -20,8 +20,16 @@ matrix:
env: TOXENV=py37-coverage
- python: pypy3.5-6.0
env: TOXENV=pypy3
+ - os: osx
+ language: generic
+ env: TOXENV=py36
+
+before_install:
+ - ./scripts/before_install.sh
+
install:
- pip install tox
+
script:
- tox
after_success:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 6635a5af..a19bee52 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -12,10 +12,19 @@ Internal:
Planned:
- profile support for common project types (black, django, google, etc)
-### 4.3.9 - Feburary 25, 2019 - hot fix release
+### 4.3.10 - March 2, 2019 - hot fix release
+- Fixed Windows incompatibilities (Issue #835)
+- Fixed relative import sorting bug (Issue #417)
+- Fixed "no_lines_before" to also be respected from previous empty sections.
+- Fixed slow-down introduced by finders mechanism by adding a LRU cache (issue #848)
+- Fixed issue #842 default encoding not-set in Python2
+- Restored Windows automated testing
+- Added Mac automated testing
+
+### 4.3.9 - February 25, 2019 - hot fix release
- Fixed a bug that led to an incompatibility with black: #831
-### 4.3.8 - Feburary 25, 2019 - hot fix release
+### 4.3.8 - February 25, 2019 - hot fix release
- Fixed a bug that led to the recursive option not always been available from the command line.
### 4.3.7 - February 25, 2019 - hot fix release
diff --git a/README.rst b/README.rst
index 90e4f9a5..f87c4504 100644
--- a/README.rst
+++ b/README.rst
@@ -23,6 +23,9 @@
:alt: Join the chat at https://gitter.im/timothycrosley/isort
:target: https://gitter.im/timothycrosley/isort?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge
+.. image:: https://pepy.tech/badge/isort
+ :alt: Downloads
+ :target: https://pepy.tech/project/isort
isort your python imports for you so you don't have to.
diff --git a/isort/__init__.py b/isort/__init__.py
index 63034de6..e3af789b 100644
--- a/isort/__init__.py
+++ b/isort/__init__.py
@@ -22,4 +22,4 @@ OTHER DEALINGS IN THE SOFTWARE.
from . import settings # noqa: F401
from .isort import SortImports # noqa: F401
-__version__ = "4.3.9"
+__version__ = "4.3.10"
diff --git a/isort/isort.py b/isort/isort.py
index 44a1c9e3..05227cb9 100644
--- a/isort/isort.py
+++ b/isort/isort.py
@@ -34,6 +34,8 @@ from datetime import datetime
from difflib import unified_diff
from typing import TYPE_CHECKING, Any, Dict, Iterable, List, Mapping, Optional, Sequence, Tuple
+from isort import utils
+
from . import settings
from .finders import FindersManager
from .natural import nsorted
@@ -46,7 +48,6 @@ if TYPE_CHECKING:
'straight': Dict[str, Any],
'from': Dict[str, Any]
})
-
CommentsDict = TypedDict('CommentsDict', {
'from': Dict[str, Any],
'straight': Dict[str, Any],
@@ -74,48 +75,21 @@ class SortImports(object):
settings_path = os.path.dirname(os.path.abspath(file_path))
settings_path = settings_path or os.getcwd()
- self.config = settings.from_path(settings_path).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.
- if access_key != 'sections' and type(self.config.get(access_key)) in (list, tuple):
- if key.startswith('not_'):
- self.config[access_key] = list(set(self.config[access_key]).difference(value))
- else:
- self.config[access_key] = list(set(self.config[access_key]).union(value))
- else:
- self.config[key] = value
-
- if self.config['force_alphabetical_sort']:
- self.config.update({'force_alphabetical_sort_within_sections': True,
- 'no_sections': True,
- 'lines_between_types': 1,
- 'from_first': True})
-
- indent = str(self.config['indent'])
- if indent.isdigit():
- indent = " " * int(indent)
- else:
- indent = indent.strip("'").strip('"')
- if indent.lower() == "tab":
- indent = "\t"
- self.config['indent'] = indent
-
- self.config['comment_prefix'] = self.config['comment_prefix'].strip("'").strip('"')
+ self.config = settings.prepare_config(settings_path, **setting_overrides)
self.place_imports = {} # type: Dict[str, List[str]]
self.import_placements = {} # type: Dict[str, str]
self.remove_imports = [self._format_simplified(removal) for removal in self.config['remove_imports']]
self.add_imports = [self._format_natural(addition) for addition in self.config['add_imports']]
- self._section_comments = ["# " + value for key, value in self.config.items() if
- key.startswith('import_heading') and value]
+ self._section_comments = ["# " + value for key, value in self.config.items()
+ if key.startswith('import_heading') and value]
self.file_encoding = 'utf-8'
file_name = file_path
self.file_path = file_path or ""
if file_path:
file_path = os.path.abspath(file_path)
- if settings.should_skip(file_path, self.config):
+ if settings.file_should_be_skipped(file_path, self.config):
self.skipped = True
if self.config['verbose']:
print("WARNING: {0} was skipped as it's listed in 'skip' setting"
@@ -137,15 +111,11 @@ class SortImports(object):
if self.config['line_ending']:
self.line_separator = self.config['line_ending']
else:
- if '\r\n' in file_contents:
- self.line_separator = '\r\n'
- elif '\r' in file_contents:
- self.line_separator = '\r'
- else:
- self.line_separator = '\n'
+ self.line_separator = utils.infer_line_separator(file_contents)
+
self.in_lines = file_contents.split(self.line_separator)
- self.original_length = len(self.in_lines)
- if (self.original_length > 1 or self.in_lines[:1] not in ([], [""])) or self.config['force_adds']:
+ self.original_num_of_lines = len(self.in_lines)
+ if (self.original_num_of_lines > 1 or self.in_lines[:1] not in ([], [""])) or self.config['force_adds']:
for add_import in self.add_imports:
self.in_lines.append(add_import)
self.number_of_lines = len(self.in_lines)
@@ -169,7 +139,7 @@ class SortImports(object):
self._parse()
if self.import_index != -1:
self._add_formatted_imports()
- self.length_change = len(self.out_lines) - self.original_length
+ self.length_change = len(self.out_lines) - self.original_num_of_lines
while self.out_lines and self.out_lines[-1].strip() == "":
self.out_lines.pop(-1)
self.out_lines.append("")
@@ -532,7 +502,7 @@ class SortImports(object):
import_statement = new_import_statement
line_length -= 1
new_import_statement = formatter(import_start, copy.copy(from_imports),
- dynamic_indent, indent, line_length, comments)
+ dynamic_indent, indent, line_length, comments)
lines = new_import_statement.split(self.line_separator)
if import_statement.count(self.line_separator) == 0:
return self._wrap(import_statement)
@@ -618,7 +588,7 @@ class SortImports(object):
output.pop(0)
output_at = 0
- if self.import_index < self.original_length:
+ if self.import_index < self.original_num_of_lines:
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
diff --git a/isort/main.py b/isort/main.py
index 80dbc712..4d6d5bd1 100644
--- a/isort/main.py
+++ b/isort/main.py
@@ -28,7 +28,7 @@ from typing import Any, Dict, Iterable, Iterator, List, MutableMapping, Optional
import setuptools
from isort import SortImports, __version__
-from isort.settings import DEFAULT_SECTIONS, WrapModes, default, from_path, should_skip
+from isort.settings import DEFAULT_SECTIONS, WrapModes, default, file_should_be_skipped, from_path
INTRO = r"""
/#######################################################################\
@@ -96,7 +96,7 @@ def iter_source_code(paths: Iterable[str], config: MutableMapping[str, Any], ski
for path in paths:
if os.path.isdir(path):
- if should_skip(path, config, os.getcwd()):
+ if file_should_be_skipped(path, config, os.getcwd()):
skipped.append(path)
continue
@@ -104,13 +104,13 @@ def iter_source_code(paths: Iterable[str], config: MutableMapping[str, Any], ski
path, topdown=True, followlinks=True
):
for dirname in list(dirnames):
- if should_skip(dirname, config, dirpath):
+ if file_should_be_skipped(dirname, config, dirpath):
skipped.append(dirname)
dirnames.remove(dirname)
for filename in filenames:
filepath = os.path.join(dirpath, filename)
if is_python_file(filepath):
- if should_skip(filename, config, dirpath):
+ if file_should_be_skipped(filename, config, dirpath):
skipped.append(filename)
else:
yield filepath
diff --git a/isort/settings.py b/isort/settings.py
index 06d1e70d..165e500a 100644
--- a/isort/settings.py
+++ b/isort/settings.py
@@ -184,6 +184,38 @@ def from_path(path: str) -> Dict[str, Any]:
return computed_settings
+def prepare_config(settings_path: str, **setting_overrides: Any) -> Dict[str, Any]:
+ config = from_path(settings_path).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.
+ if access_key != 'sections' and type(config.get(access_key)) in (list, tuple):
+ if key.startswith('not_'):
+ config[access_key] = list(set(config[access_key]).difference(value))
+ else:
+ config[access_key] = list(set(config[access_key]).union(value))
+ else:
+ config[key] = value
+
+ if config['force_alphabetical_sort']:
+ config.update({'force_alphabetical_sort_within_sections': True,
+ 'no_sections': True,
+ 'lines_between_types': 1,
+ 'from_first': True})
+
+ indent = str(config['indent'])
+ if indent.isdigit():
+ indent = " " * int(indent)
+ else:
+ indent = indent.strip("'").strip('"')
+ if indent.lower() == "tab":
+ indent = "\t"
+ config['indent'] = indent
+
+ config['comment_prefix'] = config['comment_prefix'].strip("'").strip('"')
+ return config
+
+
def _update_settings_with_config(
path: str,
name: str,
@@ -315,7 +347,7 @@ def _get_config_data(file_path: str, sections: Iterable[str]) -> Dict[str, Any]:
settings.update(config_section)
else:
warnings.warn(
- "Found %s but toml package is not installed. To configure"
+ "Found %s but toml package is not installed. To configure "
"isort with %s, install with 'isort[pyproject]'." % (file_path, file_path)
)
else:
@@ -338,7 +370,7 @@ def _get_config_data(file_path: str, sections: Iterable[str]) -> Dict[str, Any]:
return settings
-def should_skip(
+def file_should_be_skipped(
filename: str,
config: Mapping[str, Any],
path: str = '/'
diff --git a/isort/utils.py b/isort/utils.py
index 1f1b5143..0f6f57bf 100644
--- a/isort/utils.py
+++ b/isort/utils.py
@@ -52,3 +52,12 @@ def difference(a: Iterable[Any], b: Container[Any]) -> List[Any]:
if item not in b:
d.append(item)
return d
+
+
+def infer_line_separator(file_contents: str) -> str:
+ if '\r\n' in file_contents:
+ return '\r\n'
+ elif '\r' in file_contents:
+ return '\r'
+ else:
+ return '\n'
diff --git a/scripts/before_install.sh b/scripts/before_install.sh
new file mode 100755
index 00000000..fa86a770
--- /dev/null
+++ b/scripts/before_install.sh
@@ -0,0 +1,28 @@
+#! /bin/bash
+
+echo $TRAVIS_OS_NAME
+
+ if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then
+
+ # Travis has an old version of pyenv by default, upgrade it
+ brew update > /dev/null 2>&1
+ brew outdated pyenv || brew upgrade pyenv
+
+ pyenv --version
+
+ # Find the latest requested version of python
+ case "$TOXENV" in
+ py34)
+ python_minor=4;;
+ py35)
+ python_minor=5;;
+ py36)
+ python_minor=6;;
+ py37)
+ python_minor=7;;
+ esac
+ latest_version=`pyenv install --list | grep -e "^[ ]*3\.$python_minor" | tail -1`
+
+ pyenv install $latest_version
+ pyenv local $latest_version
+fi
diff --git a/setup.py b/setup.py
index 6858ad4e..3a4360b7 100755
--- a/setup.py
+++ b/setup.py
@@ -6,7 +6,7 @@ with open('README.rst') as f:
readme = f.read()
setup(name='isort',
- version='4.3.9',
+ version='4.3.10',
description='A Python utility / library to sort Python imports.',
long_description=readme,
author='Timothy Crosley',