Skip to content

Commit

Permalink
Merge pull request #1490 from PyCQA/issue/1488/isort-mangling-lines-t…
Browse files Browse the repository at this point in the history
…hat-start-with-from

Issue/1488/isort mangling lines that start with from
  • Loading branch information
timothycrosley committed Sep 20, 2020
2 parents 7431db7 + 8095ede commit 27768b0
Show file tree
Hide file tree
Showing 4 changed files with 166 additions and 2 deletions.
4 changes: 2 additions & 2 deletions .cruft.json
@@ -1,6 +1,6 @@
{
"template": "https://github.com/timothycrosley/cookiecutter-python/",
"commit": "4fe165a760a98a06d3fbef89aae3149767e489f3",
"commit": "ff6836bfaa247c65ff50b39c520ed12d91bf5a20",
"context": {
"cookiecutter": {
"full_name": "Timothy Crosley",
Expand All @@ -13,4 +13,4 @@
}
},
"directory": ""
}
}
3 changes: 3 additions & 0 deletions CHANGELOG.md
Expand Up @@ -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.

Expand Down
29 changes: 29 additions & 0 deletions isort/core.py
Expand Up @@ -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()) :]
Expand Down Expand Up @@ -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


Expand Down
132 changes: 132 additions & 0 deletions tests/unit/test_regressions.py
Expand Up @@ -949,3 +949,135 @@ def test_import_sorting_shouldnt_be_endless_with_headers_issue_1454():
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)

0 comments on commit 27768b0

Please sign in to comment.