summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTimothy Edmund Crosley <timothy.crosley@gmail.com>2020-09-20 15:49:07 -0700
committerGitHub <noreply@github.com>2020-09-20 15:49:07 -0700
commit27768b047aa1908197a1e1bb0e3bcbd85241a235 (patch)
treee506b2a6dc640218fd3b1794368a017cd1593471
parent7431db7744ca858e8b6787b571c66c5140582918 (diff)
parent8095ede4bf35ceb89c2df3267c65b0accddc2ce6 (diff)
downloadisort-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.json4
-rw-r--r--CHANGELOG.md3
-rw-r--r--isort/core.py29
-rw-r--r--tests/unit/test_regressions.py132
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)