diff --git a/CHANGELOG.md b/CHANGELOG.md index dd6f8163a..03d415f50 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ Find out more about isort's release policy [here](https://pycqa.github.io/isort/ - Implemented #1661: Added "wemake" profile. - Implemented #1669: Parallel (`-j`) now defaults to number of CPU cores if no value is provided. - Implemented #1668: Added a safeguard against accidental usage against /. + - Implemented #1638 / #1644: Provide a flag `--overwrite-in-place` to ensure same file handle is used after sorting. ### 5.7.0 December 30th 2020 - Fixed #1612: In rare circumstances an extra comma is added after import and before comment. diff --git a/isort/api.py b/isort/api.py index 024b75ac5..0cf70845f 100644 --- a/isort/api.py +++ b/isort/api.py @@ -384,7 +384,10 @@ def sort_file( ): return False source_file.stream.close() - tmp_file.replace(source_file.path) + if config.overwrite_in_place: + source_file.path.write_bytes(tmp_file.read_bytes()) + else: + tmp_file.replace(source_file.path) if not config.quiet: print(f"Fixing {source_file.path}") finally: diff --git a/isort/main.py b/isort/main.py index 0dedcd408..bdf6a89dd 100644 --- a/isort/main.py +++ b/isort/main.py @@ -207,6 +207,14 @@ def _build_arg_parser() -> argparse.ArgumentParser: dest="write_to_stdout", action="store_true", ) + general_group.add_argument( + "--overwrite-in-place", + help="Tells isort to overwrite in place using the same file handle." + "Comes at a performance and memory usage penalty over it's standard " + "approach but ensures all file flags and modes stay unchanged.", + dest="overwrite_in_place", + action="store_true", + ) general_group.add_argument( "--show-config", dest="show_config", diff --git a/isort/settings.py b/isort/settings.py index 1ea12179e..c7effa5d5 100644 --- a/isort/settings.py +++ b/isort/settings.py @@ -206,6 +206,7 @@ class _Config: follow_links: bool = True indented_import_headings: bool = True honor_case_in_force_sorted_sections: bool = False + overwrite_in_place: bool = False def __post_init__(self): py_version = self.py_version diff --git a/tests/unit/test_api.py b/tests/unit/test_api.py index 2247d8fc5..bffa7fca2 100644 --- a/tests/unit/test_api.py +++ b/tests/unit/test_api.py @@ -34,6 +34,11 @@ def test_sort_file(imperfect) -> None: assert imperfect.read() == fixed_content +def test_sort_file_in_place(imperfect) -> None: + assert api.sort_file(imperfect, overwrite_in_place=True) + assert imperfect.read() == fixed_content + + def test_sort_file_to_stdout(capsys, imperfect) -> None: assert api.sort_file(imperfect, write_to_stdout=True) out, _ = capsys.readouterr() diff --git a/tests/unit/test_main.py b/tests/unit/test_main.py index 133a94883..eb1970901 100644 --- a/tests/unit/test_main.py +++ b/tests/unit/test_main.py @@ -78,6 +78,7 @@ def test_parse_args(): assert main.parse_args(["--csi"]) == {"combine_straight_imports": True} assert main.parse_args(["--combine-straight-imports"]) == {"combine_straight_imports": True} assert main.parse_args(["--dont-follow-links"]) == {"follow_links": False} + assert main.parse_args(["--overwrite-in-place"]) == {"overwrite_in_place": True} def test_ascii_art(capsys):