From ad49f79cfd88807190e20d664a799e8a660a79d8 Mon Sep 17 00:00:00 2001 From: Timothy Crosley Date: Tue, 7 Jan 2020 12:01:42 -0800 Subject: [PATCH] Fix issue #969: Add support for single line exclusions --- isort/main.py | 7 +++++++ isort/output.py | 6 ++++-- isort/profiles.py | 7 ++++++- isort/settings.py | 1 + tests/test_isort.py | 20 ++++++++++++++++++++ 5 files changed, 38 insertions(+), 3 deletions(-) diff --git a/isort/main.py b/isort/main.py index b9b866874..459e786ee 100644 --- a/isort/main.py +++ b/isort/main.py @@ -422,6 +422,13 @@ def parse_args(argv: Optional[Sequence[str]] = None) -> Dict[str, Any]: action="store_true", help="Forces all from imports to appear on their own line", ) + parser.add_argument( + "--nsl", + "--single-line-exclusions", + help="One or more modules to exclude from the single line rule.", + dest="single_line_exclusions", + action="append", + ) parser.add_argument( "--sp", "--settings-path", diff --git a/isort/output.py b/isort/output.py index cd925c91c..27fbd3973 100644 --- a/isort/output.py +++ b/isort/output.py @@ -239,7 +239,9 @@ def _with_from_imports( import_start = f"from {module} {import_type} " from_imports = list(parsed.imports[section]["from"][module]) - if not config.no_inline_sort or config.force_single_line: + if not config.no_inline_sort or ( + config.force_single_line and module not in config.single_line_exclusions + ): from_imports = sorting.naturally( from_imports, key=lambda key: sorting.module_key( @@ -288,7 +290,7 @@ def _with_from_imports( config, ) from_imports = [] - elif config.force_single_line: + elif config.force_single_line and module not in config.single_line_exclusions: import_statement = "" while from_imports: from_import = from_imports.pop(0) diff --git a/isort/profiles.py b/isort/profiles.py index 1210c8ef0..910da9357 100644 --- a/isort/profiles.py +++ b/isort/profiles.py @@ -15,7 +15,12 @@ "line_length": 79, } pycharm = {"multi_line_output": 3, "force_grid_wrap": 2} -google = {"force_single_line": True, "force_sort_within_sections": True, "lexicographical": True} +google = { + "force_single_line": True, + "force_sort_within_sections": True, + "lexicographical": True, + "single_line_exclusions": ("typing",), +} open_stack = { "force_single_line": True, "force_sort_within_sections": True, diff --git a/isort/settings.py b/isort/settings.py index 04b488f1c..f51d78c87 100644 --- a/isort/settings.py +++ b/isort/settings.py @@ -142,6 +142,7 @@ class _Config: remove_imports: FrozenSet[str] = frozenset() reverse_relative: bool = False force_single_line: bool = False + single_line_exclusions: Tuple[str, ...] = () default_section: str = "FIRSTPARTY" import_headings: Dict[str, str] = field(default_factory=dict) balanced_wrapping: bool = False diff --git a/tests/test_isort.py b/tests/test_isort.py index 0228b414a..efff42c47 100644 --- a/tests/test_isort.py +++ b/tests/test_isort.py @@ -4702,3 +4702,23 @@ def test_noqa_issue_1065() -> None: from flask_security.signals import user_registered # noqa """ assert SortImports(file_contents=test_input).output == expected_output + + +def test_single_line_exclusions(): + test_input = """ +# start comment +from os import path, system +from typing import List, TypeVar +""" + expected_output = """ +# start comment +from os import path +from os import system +from typing import List, TypeVar +""" + assert ( + SortImports( + file_contents=test_input, force_single_line=True, single_line_exclusions=("typing",) + ).output + == expected_output + )