Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix sort_reexports code mangling #2283

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 12 additions & 8 deletions isort/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,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 +134,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 +151,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 +239,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 +259,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 +362,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