diff options
author | Timothy Edmund Crosley <timothy.crosley@gmail.com> | 2019-02-16 18:17:36 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-02-16 18:17:36 -0800 |
commit | 880f6798ee1bb5ed81779217ce45f221f0e50c06 (patch) | |
tree | 13f358f45b7753f98568ca7a83521676978303e8 | |
parent | bf67c678c13f5052623a968764263e934551db62 (diff) | |
parent | 537712f40c1b1b6d49be08444c2cae50157db5ca (diff) | |
download | isort-880f6798ee1bb5ed81779217ce45f221f0e50c06.tar.gz |
Merge pull request #775 from mattbennett/nondeterministic-forced-separate
Maintain order when loading iterable values from config files
-rw-r--r-- | isort/settings.py | 7 | ||||
-rw-r--r-- | isort/utils.py | 23 | ||||
-rw-r--r-- | test_isort.py | 25 |
3 files changed, 52 insertions, 3 deletions
diff --git a/isort/settings.py b/isort/settings.py index cb047158..8d6be959 100644 --- a/isort/settings.py +++ b/isort/settings.py @@ -35,6 +35,7 @@ from collections import namedtuple from distutils.util import strtobool from .pie_slice import lru_cache +from .utils import difference, union try: import configparser @@ -217,11 +218,11 @@ def _update_with_config_file(file_path, sections, computed_settings): else: existing_data = set(computed_settings.get(access_key, default.get(access_key))) if key.startswith('not_'): - computed_settings[access_key] = list(existing_data.difference(_as_list(value))) + computed_settings[access_key] = difference(existing_data, _as_list(value)) elif key.startswith('known_'): - computed_settings[access_key] = list(existing_data.union(_abspaths(cwd, _as_list(value)))) + computed_settings[access_key] = union(existing_data, _abspaths(cwd, _as_list(value))) else: - computed_settings[access_key] = list(existing_data.union(_as_list(value))) + computed_settings[access_key] = union(existing_data, _as_list(value)) elif existing_value_type == bool: # Only some configuration formats support native boolean values. if not isinstance(value, bool): diff --git a/isort/utils.py b/isort/utils.py index 9206c88e..ce4e588e 100644 --- a/isort/utils.py +++ b/isort/utils.py @@ -28,3 +28,26 @@ def chdir(path): yield finally: os.chdir(curdir) + + +def union(a, b): + """ Return a list of items that are in `a` or `b` + """ + u = [] + for item in a: + if item not in u: + u.append(item) + for item in b: + if item not in u: + u.append(item) + return u + + +def difference(a, b): + """ Return a list of items from `a` that are not in `b`. + """ + d = [] + for item in a: + if item not in b: + d.append(item) + return d diff --git a/test_isort.py b/test_isort.py index ca826a5a..34d19569 100644 --- a/test_isort.py +++ b/test_isort.py @@ -2565,6 +2565,31 @@ def test_requirements_finder(tmpdir): req_file.remove() +def test_forced_separate_is_deterministic_issue_774(tmpdir): + + config_file = tmpdir.join('setup.cfg') + config_file.write( + "[isort]\n" + "forced_separate:\n" + " separate1\n" + " separate2\n" + " separate3\n" + " separate4\n" + ) + + test_input = ('import time\n' + '\n' + 'from separate1 import foo\n' + '\n' + 'from separate2 import bar\n' + '\n' + 'from separate3 import baz\n' + '\n' + 'from separate4 import quux\n') + + assert SortImports(file_contents=test_input, settings_path=config_file.strpath).output == test_input + + PIPFILE = """ [[source]] url = "https://pypi.org/simple" |