diff options
author | Timothy Edmund Crosley <timothy.crosley@gmail.com> | 2020-09-20 15:49:07 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-09-20 15:49:07 -0700 |
commit | 27768b047aa1908197a1e1bb0e3bcbd85241a235 (patch) | |
tree | e506b2a6dc640218fd3b1794368a017cd1593471 | |
parent | 7431db7744ca858e8b6787b571c66c5140582918 (diff) | |
parent | 8095ede4bf35ceb89c2df3267c65b0accddc2ce6 (diff) | |
download | isort-27768b047aa1908197a1e1bb0e3bcbd85241a235.tar.gz |
Merge pull request #1490 from PyCQA/issue/1488/isort-mangling-lines-that-start-with-from
Issue/1488/isort mangling lines that start with from
-rw-r--r-- | .cruft.json | 4 | ||||
-rw-r--r-- | CHANGELOG.md | 3 | ||||
-rw-r--r-- | isort/core.py | 29 | ||||
-rw-r--r-- | tests/unit/test_regressions.py | 132 |
4 files changed, 166 insertions, 2 deletions
diff --git a/.cruft.json b/.cruft.json index f70213bc..dcbd6c8e 100644 --- a/.cruft.json +++ b/.cruft.json @@ -1,6 +1,6 @@ { "template": "https://github.com/timothycrosley/cookiecutter-python/", - "commit": "4fe165a760a98a06d3fbef89aae3149767e489f3", + "commit": "ff6836bfaa247c65ff50b39c520ed12d91bf5a20", "context": { "cookiecutter": { "full_name": "Timothy Crosley", @@ -13,4 +13,4 @@ } }, "directory": "" -} +}
\ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index f6a0ce5a..1d8a50bd 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.5.3 [Hotfix] September 20, 2020 + - Fixed #1488: in rare cases isort can mangle `yield from` or `raise from` statements. + ### 5.5.2 [Hotfix] September 9, 2020 - Fixed #1469: --diff option is ignored when input is from stdin. diff --git a/isort/core.py b/isort/core.py index f3197b99..d1e945d4 100644 --- a/isort/core.py +++ b/isort/core.py @@ -306,6 +306,7 @@ def process( raw_import_section += line if not contains_imports: output_stream.write(import_section) + else: leading_whitespace = import_section[: -len(import_section.lstrip())] trailing_whitespace = import_section[len(import_section.rstrip()) :] @@ -361,6 +362,34 @@ def process( output_stream.write(line) not_imports = False + if stripped_line and not in_quote and not import_section and not next_import_section: + if stripped_line == "yield": + while not stripped_line or stripped_line == "yield": + new_line = input_stream.readline() + if not new_line: + break + + output_stream.write(new_line) + stripped_line = new_line.strip().split("#")[0] + + if stripped_line.startswith("raise") or stripped_line.startswith("yield"): + if "(" in stripped_line: + while ")" not in stripped_line: + new_line = input_stream.readline() + if not new_line: + break + + output_stream.write(new_line) + stripped_line = new_line.strip().split("#")[0] + + while stripped_line.endswith("\\"): + new_line = input_stream.readline() + if not new_line: + break + + output_stream.write(new_line) + stripped_line = new_line.strip().split("#")[0] + return made_changes diff --git a/tests/unit/test_regressions.py b/tests/unit/test_regressions.py index 752adc34..4869d444 100644 --- a/tests/unit/test_regressions.py +++ b/tests/unit/test_regressions.py @@ -949,3 +949,135 @@ except ImportError as e: import_heading_thirdparty="related third party imports", show_diff=True, ) + + +def test_isort_should_leave_non_import_from_lines_alone_issue_1488(): + """isort should never mangle non-import from statements. + See: https://github.com/PyCQA/isort/issues/1488 + """ + raise_from_should_be_ignored = """ +raise SomeException("Blah") \\ + from exceptionsInfo.popitem()[1] +""" + assert isort.check_code(raise_from_should_be_ignored, show_diff=True) + + yield_from_should_be_ignored = """ +def generator_function(): + yield \\ + from other_function()[1] +""" + assert isort.check_code(yield_from_should_be_ignored, show_diff=True) + + wont_ignore_comment_contiuation = """ +# one + +# two + + +def function(): + # three \\ + import b + import a +""" + assert ( + isort.code(wont_ignore_comment_contiuation) + == """ +# one + +# two + + +def function(): + # three \\ + import a + import b +""" + ) + + will_ignore_if_non_comment_continuation = """ +# one + +# two + + +def function(): + raise \\ + import b + import a +""" + assert isort.check_code(will_ignore_if_non_comment_continuation, show_diff=True) + + yield_from_parens_should_be_ignored = """ +def generator_function(): + ( + yield + from other_function()[1] + ) +""" + assert isort.check_code(yield_from_parens_should_be_ignored, show_diff=True) + + yield_from_lots_of_parens_and_space_should_be_ignored = """ +def generator_function(): + ( + ( + (((( + ((((( + (( + ((( + yield + + + + from other_function()[1] + ))))))))))))) + ))) +""" + assert isort.check_code(yield_from_lots_of_parens_and_space_should_be_ignored, show_diff=True) + + yield_from_should_be_ignored_when_following_import_statement = """ +def generator_function(): + import os + + yield \\ + from other_function()[1] +""" + assert isort.check_code( + yield_from_should_be_ignored_when_following_import_statement, show_diff=True + ) + + yield_at_file_end_ignored = """ +def generator_function(): + ( + ( + (((( + ((((( + (( + ((( + yield +""" + assert isort.check_code(yield_at_file_end_ignored, show_diff=True) + + raise_at_file_end_ignored = """ +def generator_function(): + ( + ( + (((( + ((((( + (( + ((( + raise ( +""" + assert isort.check_code(raise_at_file_end_ignored, show_diff=True) + + raise_from_at_file_end_ignored = """ +def generator_function(): + ( + ( + (((( + ((((( + (( + ((( + raise \\ + from \\ +""" + assert isort.check_code(raise_from_at_file_end_ignored, show_diff=True) |