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

Resolved #1502: Improved float-to-top behavior when there is an exist… #1503

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Expand Up @@ -7,6 +7,7 @@ Find out more about isort's release policy [here](https://pycqa.github.io/isort/
### 5.6.0 TBD
- Implemented #1433: Provide helpful feedback in case a custom config file is specified without a configuration.
- Implemented #1494: Default to sorting imports within `.pxd` files.
- Implemented #1502: Improved float-to-top behavior when there is an existing import section present at top-of-file.
- Improved handling of unsupported configuration option errors (see #1475).
- Fixed #1463: Better interactive documentation for future option.
- Fixed #1461: Quiet config option not respected by file API in some circumstances.
Expand Down
3 changes: 3 additions & 0 deletions isort/core.py
Expand Up @@ -83,6 +83,9 @@ def process(
if line == "# isort: off\n":
isort_off = True
if current:
if add_imports:
current += line_separator + line_separator.join(add_imports)
add_imports = []
parsed = parse.file_contents(current, config=config)
extra_space = ""
while current and current[-1] == "\n":
Expand Down
2 changes: 2 additions & 0 deletions isort/parse.py
Expand Up @@ -210,6 +210,8 @@ def file_contents(contents: str, config: Config = DEFAULT_CONFIG) -> ParsedConte
and not lstripped_line.startswith("#")
and not lstripped_line.startswith("'''")
and not lstripped_line.startswith('"""')
and not lstripped_line.startswith("import")
and not lstripped_line.startswith("from")
):
import_index = index - 1
while import_index and not in_lines[import_index - 1]:
Expand Down
122 changes: 112 additions & 10 deletions tests/unit/test_ticketed_features.py
Expand Up @@ -60,7 +60,8 @@ def my_function_2():
""",
float_to_top=True,
)
== """import os
== """
import os
import sys


Expand Down Expand Up @@ -90,7 +91,8 @@ def my_function_2():
""",
float_to_top=True,
)
== """import os
== """
import os


def my_function_1():
Expand All @@ -105,10 +107,9 @@ def my_function_2():
"""
)


assert (
isort.code(
"""
assert (
isort.code(
"""
import os


Expand All @@ -129,9 +130,10 @@ def my_function_2():

import a
""",
float_to_top=True,
)
== """import os
float_to_top=True,
)
== """
import os


def my_function_1():
Expand All @@ -151,7 +153,7 @@ def y():
def my_function_2():
pass
"""
)
)


def test_isort_provides_official_api_for_diff_output_issue_1335():
Expand Down Expand Up @@ -746,3 +748,103 @@ def test_isort_should_warn_on_empty_custom_config_issue_1433(tmpdir):
with pytest.warns(None) as warning:
assert Config(settings_file=str(settings_file)).quiet
assert not warning


def test_float_to_top_should_respect_existing_newlines_between_imports_issue_1502():
"""When a file has an existing top of file import block before code but after comments
isort's float to top feature should respect the existing spacing between the top file comment
and the import statements.
See: https://github.com/PyCQA/isort/issues/1502
"""
assert isort.check_code(
"""#!/bin/bash
'''My comment'''

import a

x = 1
""",
float_to_top=True,
show_diff=True,
)
assert isort.check_code(
"""#!/bin/bash
'''My comment'''


import a

x = 1
""",
float_to_top=True,
show_diff=True,
)
assert (
isort.code(
"""#!/bin/bash
'''My comment'''


import a

x = 1
""",
float_to_top=True,
add_imports=["import b"],
)
== """#!/bin/bash
'''My comment'''


import a
import b

x = 1
"""
)

assert (
isort.code(
"""#!/bin/bash
'''My comment'''


def my_function():
pass


import a
""",
float_to_top=True,
)
== """#!/bin/bash
'''My comment'''
import a


def my_function():
pass
"""
)

assert (
isort.code(
"""#!/bin/bash
'''My comment'''


def my_function():
pass
""",
add_imports=["import os"],
float_to_top=True,
)
== """#!/bin/bash
'''My comment'''
import os


def my_function():
pass
"""
)