Repository: PyCQA/isort

Issue:
BUG: --sort-reexports don't work with multiple lines __all__
```python
import datetime

from mylib import (
    module1,
    module2,
    module3,
    module4,
)

__all__ = (
    "func1",
    "func2",
    "func3",
    "func4",
)
```

after using `isort file.py --sort-reexports`, becomes:
```python
import datetime

fro__all__ = ('func1', 'func2', 'func3', 'func4')
```
It seems to me that there is a problem with calculating the current index when using reexports in cases where we use multiline exports or add comments _to the beginning of the file_.

Discussion:

Patch:
diff --git a/isort/core.py b/isort/core.py
index 10103854..472d914d 100644
--- a/isort/core.py
+++ b/isort/core.py
@@ -27,6 +27,8 @@ CODE_SORT_COMMENTS = (
 LITERAL_TYPE_MAPPING = {"(": "tuple", "[": "list", "{": "set"}
 
 
+# Ignore DeepSource cyclomatic complexity check for this function.
+# skipcq: PY-R1000
 def process(
     input_stream: TextIO,
     output_stream: TextIO,
@@ -75,7 +77,7 @@ def process(
     verbose_output: List[str] = []
     lines_before: List[str] = []
     is_reexport: bool = False
-    sort_section_pointer: int = 0
+    reexport_rollback: int = 0
 
     if config.float_to_top:
         new_input = ""
@@ -134,7 +136,8 @@ def process(
 
             if code_sorting and code_sorting_section:
                 if is_reexport:
-                    output_stream.seek(sort_section_pointer, 0)
+                    output_stream.seek(output_stream.tell() - reexport_rollback)
+                    reexport_rollback = 0
                 sorted_code = textwrap.indent(
                     isort.literal.assignment(
                         code_sorting_section,
@@ -150,7 +153,9 @@ def process(
                     line_separator=line_separator,
                     ignore_whitespace=config.ignore_whitespace,
                 )
-                sort_section_pointer += output_stream.write(sorted_code)
+                output_stream.write(sorted_code)
+                if is_reexport:
+                    output_stream.truncate()
         else:
             stripped_line = line.strip()
             if stripped_line and not line_separator:
@@ -236,8 +241,8 @@ def process(
                     code_sorting_indent = line[: -len(line.lstrip())]
                     not_imports = True
                     code_sorting_section += line
+                    reexport_rollback = len(line)
                     is_reexport = True
-                    sort_section_pointer -= len(line)
                 elif code_sorting:
                     if not stripped_line:
                         sorted_code = textwrap.indent(
@@ -256,8 +261,11 @@ def process(
                             ignore_whitespace=config.ignore_whitespace,
                         )
                         if is_reexport:
-                            output_stream.seek(sort_section_pointer, 0)
-                        sort_section_pointer += output_stream.write(sorted_code)
+                            output_stream.seek(output_stream.tell() - reexport_rollback)
+                            reexport_rollback = 0
+                        output_stream.write(sorted_code)
+                        if is_reexport:
+                            output_stream.truncate()
                         not_imports = True
                         code_sorting = False
                         code_sorting_section = ""
@@ -356,8 +364,6 @@ def process(
                 else:
                     not_imports = True
 
-        sort_section_pointer += len(line)
-
         if not_imports:
             if not was_in_quote and config.lines_before_imports > -1:
                 if line.strip() == "":


Test patch:
diff --git a/tests/unit/test_isort.py b/tests/unit/test_isort.py
index 7b6743c7..eff10f69 100644
--- a/tests/unit/test_isort.py
+++ b/tests/unit/test_isort.py
@@ -2,6 +2,7 @@
 
 Should be ran using py.test by simply running py.test in the isort project directory
 """
+
 import os
 import os.path
 import subprocess
@@ -5671,3 +5672,58 @@ def test_reexport_not_last_line() -> None:
     meme = "rickroll"
 """
     assert isort.code(test_input, config=Config(sort_reexports=True)) == expd_output
+
+
+def test_reexport_multiline_import() -> None:
+    test_input = """from m import (
+    bar,
+    foo,
+)
+__all__ = [
+    "foo",
+    "bar",
+]
+"""
+    expd_output = """from m import bar, foo
+
+__all__ = ['bar', 'foo']
+"""
+    assert isort.code(test_input, config=Config(sort_reexports=True)) == expd_output
+
+
+def test_reexport_multiline_in_center() -> None:
+    test_input = """from m import (
+    bar,
+    foo,
+) 
+__all__ = [
+    "foo",
+    "bar",
+]
+
+test
+"""
+    expd_output = """from m import bar, foo
+
+__all__ = ['bar', 'foo']
+
+test
+"""
+    assert isort.code(test_input, config=Config(sort_reexports=True)) == expd_output
+
+
+def test_reexport_multiline_long_rollback() -> None:
+    test_input = """from m import foo, bar 
+__all__ = [                            "foo",
+    "bar",
+]
+
+test
+"""
+    expd_output = """from m import bar, foo
+
+__all__ = ['bar', 'foo']
+
+test
+"""
+    assert isort.code(test_input, config=Config(sort_reexports=True)) == expd_output