Skip to content

Commit

Permalink
Merge pull request #2283 from Helveg/fix-sort-reexports
Browse files Browse the repository at this point in the history
Fix `sort_reexports` code mangling
  • Loading branch information
DanielNoord authored Jan 9, 2025
2 parents 7de1829 + af02e0e commit 122c09f
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 8 deletions.
22 changes: 14 additions & 8 deletions isort/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@
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,
Expand Down Expand Up @@ -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 = ""
Expand Down Expand Up @@ -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,
Expand All @@ -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:
Expand Down Expand Up @@ -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(
Expand All @@ -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 = ""
Expand Down Expand Up @@ -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() == "":
Expand Down
56 changes: 56 additions & 0 deletions tests/unit/test_isort.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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

0 comments on commit 122c09f

Please sign in to comment.