summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTimothy Crosley <timothy.crosley@gmail.com>2020-09-20 15:52:16 -0700
committerTimothy Crosley <timothy.crosley@gmail.com>2020-09-20 15:52:16 -0700
commit9eadb379a765ab7048bbf104b45e32ddc92ac070 (patch)
tree65fec86aa3ca2318a82f59b6065ef6d06b5b067f
parent15f7723e180e790b2391d19e1c5bf51f967bd6d6 (diff)
parentec78bf395883bc396bf378a2290af6d8004ea6c3 (diff)
downloadisort-9eadb379a765ab7048bbf104b45e32ddc92ac070.tar.gz
Merge branch 'master' of https://github.com/timothycrosley/isort into develop
-rw-r--r--CHANGELOG.md3
-rw-r--r--isort/_version.py2
-rw-r--r--isort/core.py29
-rw-r--r--pyproject.toml2
-rw-r--r--tests/unit/test_regressions.py132
5 files changed, 166 insertions, 2 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index ac76e56e..b22f81d8 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -11,6 +11,9 @@ Find out more about isort's release policy [here](https://pycqa.github.io/isort/
- Fixed #1461: Quiet config option not respected by file API in some circumstances.
- Fixed #1482: pylama integration is not working correctly out-of-the-box.
+### 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/_version.py b/isort/_version.py
index 9fe27eeb..16b899cb 100644
--- a/isort/_version.py
+++ b/isort/_version.py
@@ -1 +1 @@
-__version__ = "5.5.2"
+__version__ = "5.5.3"
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/pyproject.toml b/pyproject.toml
index 4b3bdff4..db979b71 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -3,7 +3,7 @@ line-length = 100
[tool.poetry]
name = "isort"
-version = "5.5.2"
+version = "5.5.3"
description = "A Python utility / library to sort Python imports."
authors = ["Timothy Crosley <timothy.crosley@gmail.com>"]
license = "MIT"
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)