diff options
author | Timothy Edmund Crosley <timothy.crosley@gmail.com> | 2019-02-15 19:30:10 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-02-15 19:30:10 -0800 |
commit | d075644528d171d63dd8789ab1fa21a5ab7da685 (patch) | |
tree | 1a9b4097657b5c8e245bad990726bf29c791d937 | |
parent | 8d3e0653117431e062d64d5f3c9ab3022d061f3e (diff) | |
parent | 9582a8e3d06080f8c227e31fc12eb7f1d9fb5b82 (diff) | |
download | isort-d075644528d171d63dd8789ab1fa21a5ab7da685.tar.gz |
Merge branch 'develop' into test-coverage-improvements
-rw-r--r-- | isort/main.py | 5 | ||||
-rw-r--r-- | isort/settings.py | 16 | ||||
-rw-r--r-- | test_isort.py | 19 |
3 files changed, 37 insertions, 3 deletions
diff --git a/isort/main.py b/isort/main.py index b95a2999..a584c226 100644 --- a/isort/main.py +++ b/isort/main.py @@ -284,11 +284,16 @@ def parse_args(argv=None): help='Tells isort to ignore whitespace differences when --check-only is being used.') parser.add_argument('-y', '--apply', dest='apply', action='store_true', help='Tells isort to apply changes recursively without asking') + parser.add_argument('--unsafe', dest='unsafe', action='store_true', + help='Tells isort to look for files in standard library directories, etc. ' + 'where it may not be safe to operate in') parser.add_argument('files', nargs='*', help='One or more Python source files that need their imports sorted.') arguments = {key: value for key, value in vars(parser.parse_args(argv)).items() if value} if 'dont_order_by_type' in arguments: arguments['order_by_type'] = False + if arguments.pop('unsafe', False): + arguments['safety_excludes'] = False return arguments diff --git a/isort/settings.py b/isort/settings.py index 79ae6c4c..cb047158 100644 --- a/isort/settings.py +++ b/isort/settings.py @@ -27,6 +27,7 @@ from __future__ import absolute_import, division, print_function, unicode_litera import fnmatch import io import os +import re import posixpath import sys import warnings @@ -48,6 +49,10 @@ except ImportError: MAX_CONFIG_SEARCH_DEPTH = 25 # The number of parent directories isort will look for a config file within DEFAULT_SECTIONS = ('FUTURE', 'STDLIB', 'THIRDPARTY', 'FIRSTPARTY', 'LOCALFOLDER') +safety_exclude_re = re.compile( + r"/(\.eggs|\.git|\.hg|\.mypy_cache|\.nox|\.tox|\.venv|_build|buck-out|build|dist|lib/python[0-9].[0-9]+)/" +) + WrapModes = ('GRID', 'VERTICAL', 'HANGING_INDENT', 'VERTICAL_HANGING_INDENT', 'VERTICAL_GRID', 'VERTICAL_GRID_GROUPED', 'VERTICAL_GRID_GROUPED_NO_COMMA', 'NOQA') WrapModes = namedtuple('WrapModes', WrapModes)(*range(len(WrapModes))) @@ -145,7 +150,9 @@ default = {'force_to_top': [], 'show_diff': False, 'ignore_whitespace': False, 'no_lines_before': [], - 'no_inline_sort': False} + 'no_inline_sort': False, + 'safety_excludes': True, + } @lru_cache() @@ -292,8 +299,13 @@ def _get_config_data(file_path, sections): def should_skip(filename, config, path='/'): """Returns True if the file should be skipped based on the passed in settings.""" + normalized_path = posixpath.join(path.replace('\\', '/'), filename) + + if config['safety_excludes'] and safety_exclude_re.search(normalized_path): + return True + for skip_path in config['skip']: - if posixpath.abspath(posixpath.join(path.replace('\\', '/'), filename)) == posixpath.abspath(skip_path.replace('\\', '/')): + if posixpath.abspath(normalized_path) == posixpath.abspath(skip_path.replace('\\', '/')): return True position = os.path.split(filename) diff --git a/test_isort.py b/test_isort.py index 302abfc9..c0ddff7f 100644 --- a/test_isort.py +++ b/test_isort.py @@ -25,11 +25,12 @@ from __future__ import absolute_import, division, print_function, unicode_litera from tempfile import NamedTemporaryFile import io +import os import sys import pytest -from isort import finders +from isort import finders, main, settings from isort.isort import SortImports from isort.utils import exists_case_sensitive from isort.main import is_python_file @@ -2623,3 +2624,19 @@ def test_command_line(tmpdir, capfd, multiprocess): # it informs us about fixing the files: assert str(tmpdir.join("file1.py")) in out assert str(tmpdir.join("file2.py")) in out + + +@pytest.mark.parametrize('enabled', (False, True)) +def test_safety_excludes(tmpdir, enabled): + tmpdir.join("victim.py").write("# ...") + tmpdir.mkdir(".tox").join("verysafe.py").write("# ...") + tmpdir.mkdir("lib").mkdir("python3.7").join("importantsystemlibrary.py").write("# ...") + config = dict(settings.default.copy(), safety_excludes=enabled) + skipped = [] + file_names = set(os.path.relpath(f, str(tmpdir)) for f in main.iter_source_code([str(tmpdir)], config, skipped)) + if enabled: + assert file_names == {'victim.py'} + assert len(skipped) == 2 + else: + assert file_names == {'.tox/verysafe.py', 'lib/python3.7/importantsystemlibrary.py', 'victim.py'} + assert not skipped |