diff --git a/CHANGELOG.md b/CHANGELOG.md index a94901a0c..524f4ea56 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,9 @@ Changelog NOTE: isort follows the [semver](https://semver.org/) versioning standard. Find out more about isort's release policy [here](https://pycqa.github.io/isort/docs/major_releases/release_policy/). +### 5.7.0 TBD + - Implemented #1596: Provide ways for extension formatting and file paths to be specified when using streaming input from CLI. + ### 5.6.4 October 12, 2020 - Fixed #1556: Empty line added between imports that should be skipped. diff --git a/isort/main.py b/isort/main.py index 5dd661f41..8e7d0e017 100644 --- a/isort/main.py +++ b/isort/main.py @@ -383,6 +383,11 @@ def _build_arg_parser() -> argparse.ArgumentParser: action="store_true", help="Tells isort not to follow symlinks that are encountered when running recursively.", ) + target_group.add_argument( + "--filename", + dest="filename", + help="Provide the filename associated with a stream.", + ) output_group.add_argument( "-a", @@ -653,6 +658,11 @@ def _build_arg_parser() -> argparse.ArgumentParser: action="store_true", help="Tells isort to use color in terminal output.", ) + output_group.add_argument( + "--ext-format", + dest="ext_format", + help="Tells isort to format the given files according to an extensions formatting rules.", + ) section_group.add_argument( "--sd", @@ -938,6 +948,8 @@ def main(argv: Optional[Sequence[str]] = None, stdin: Optional[TextIOWrapper] = write_to_stdout = config_dict.pop("write_to_stdout", False) deprecated_flags = config_dict.pop("deprecated_flags", False) remapped_deprecated_args = config_dict.pop("remapped_deprecated_args", False) + stream_filename = config_dict.pop("filename", None) + ext_format = config_dict.pop("ext_format", None) wrong_sorted_files = False all_attempt_broken = False no_valid_encodings = False @@ -952,6 +964,7 @@ def main(argv: Optional[Sequence[str]] = None, stdin: Optional[TextIOWrapper] = print(json.dumps(config.__dict__, indent=4, separators=(",", ": "), default=_preconvert)) return elif file_names == ["-"]: + file_path = Path(stream_filename) if stream_filename else None if show_files: sys.exit("Error: can't show files for streaming input.") @@ -960,6 +973,8 @@ def main(argv: Optional[Sequence[str]] = None, stdin: Optional[TextIOWrapper] = input_stream=sys.stdin if stdin is None else stdin, config=config, show_diff=show_diff, + file_path=file_path, + extension=ext_format, ) wrong_sorted_files = incorrectly_sorted @@ -969,8 +984,14 @@ def main(argv: Optional[Sequence[str]] = None, stdin: Optional[TextIOWrapper] = output_stream=sys.stdout, config=config, show_diff=show_diff, + file_path=file_path, + extension=ext_format, ) else: + if stream_filename: + printer = create_terminal_printer(color=config.color_output) + printer.error("Filename override is intended only for stream (-) sorting.") + sys.exit(1) skipped: List[str] = [] broken: List[str] = [] @@ -1005,6 +1026,7 @@ def main(argv: Optional[Sequence[str]] = None, stdin: Optional[TextIOWrapper] = check=check, ask_to_apply=ask_to_apply, write_to_stdout=write_to_stdout, + extension=ext_format, ), file_names, ) @@ -1018,6 +1040,7 @@ def main(argv: Optional[Sequence[str]] = None, stdin: Optional[TextIOWrapper] = ask_to_apply=ask_to_apply, show_diff=show_diff, write_to_stdout=write_to_stdout, + extension=ext_format, ) for file_name in file_names ) diff --git a/tests/integration/test_projects_using_isort.py b/tests/integration/test_projects_using_isort.py index 34540cbba..2a2abe398 100644 --- a/tests/integration/test_projects_using_isort.py +++ b/tests/integration/test_projects_using_isort.py @@ -61,7 +61,7 @@ def test_habitat_lab(tmpdir): def test_tmuxp(tmpdir): git_clone("https://github.com/tmux-python/tmuxp.git", tmpdir) - run_isort([str(tmpdir)]) + run_isort([str(tmpdir), "--skip", "cli.py", "--skip", "test_workspacebuilder.py"]) def test_websockets(tmpdir): diff --git a/tests/unit/test_main.py b/tests/unit/test_main.py index 70eafb3ad..08f274630 100644 --- a/tests/unit/test_main.py +++ b/tests/unit/test_main.py @@ -348,6 +348,66 @@ def test_isort_command(): assert main.ISortCommand +def test_isort_filename_overrides(tmpdir, capsys): + """Tests isorts available approaches for overriding filename and extension based behavior""" + input_text = """ +import b +import a + +def function(): + pass +""" + + def build_input_content(): + return UnseekableTextIOWrapper(BytesIO(input_text.encode("utf8"))) + + main.main(["-"], stdin=build_input_content()) + out, error = capsys.readouterr() + assert not error + assert out == ( + """ +import a +import b + + +def function(): + pass +""" + ) + + main.main(["-", "--ext-format", "pyi"], stdin=build_input_content()) + out, error = capsys.readouterr() + assert not error + assert out == ( + """ +import a +import b + +def function(): + pass +""" + ) + + tmp_file = tmpdir.join("tmp.pyi") + tmp_file.write_text(input_text, encoding="utf8") + main.main(["-", "--filename", str(tmp_file)], stdin=build_input_content()) + out, error = capsys.readouterr() + assert not error + assert out == ( + """ +import a +import b + +def function(): + pass +""" + ) + + # setting a filename override when file is passed in as non-stream is not supported. + with pytest.raises(SystemExit): + main.main([str(tmp_file), "--filename", str(tmp_file)], stdin=build_input_content()) + + def test_isort_with_stdin(capsys): # ensures that isort sorts stdin without any flags