From 52f5134889d345ff35afdcb86501c8221b804c70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dani=C3=ABl=20van=20Noord?= <13665637+DanielNoord@users.noreply.github.com> Date: Sat, 11 Oct 2025 15:09:59 +0200 Subject: [PATCH] Format with `ruff` instead of `black` --- docs/contributing/2.-coding-standard.md | 10 +- isort/exceptions.py | 3 +- isort/output.py | 10 +- isort/parse.py | 6 +- isort/wrap_modes.py | 2 +- pyproject.toml | 3 - scripts/build_profile_docs.py | 4 +- tests/unit/test_identify.py | 27 ++- tests/unit/test_isort.py | 224 +++++++----------------- tests/unit/test_main.py | 4 +- tests/unit/test_regressions.py | 28 ++- tox.ini | 2 +- 12 files changed, 106 insertions(+), 217 deletions(-) diff --git a/docs/contributing/2.-coding-standard.md b/docs/contributing/2.-coding-standard.md index 8eeeaf19..affb5da4 100644 --- a/docs/contributing/2.-coding-standard.md +++ b/docs/contributing/2.-coding-standard.md @@ -41,16 +41,16 @@ There should be a `tests/test_$MODULE_NAME.py` file created to correspond to eve ## Automated Code Cleaners -All code submitted to Hug should be formatted using Black and isort. -Black should be run with the line length set to 100, and isort with Black compatible settings in place. +All code submitted should be formatted using Ruff and isort. +Ruff should be run with the line length set to 100, and isort with Black compatible settings in place. ## Automated Code Linting -All code submitted to hug should run through the following tools: +All code submitted should run through the following tools: -- Black and isort verification. +- Ruff and isort verification. - Flake8 - - flake8-bugbear +- flake8-bugbear - Bandit - ruff - pep8-naming diff --git a/isort/exceptions.py b/isort/exceptions.py index 443a4a8a..34d4e302 100644 --- a/isort/exceptions.py +++ b/isort/exceptions.py @@ -31,8 +31,7 @@ class ExistingSyntaxErrors(ISortError): def __init__(self, file_path: str): super().__init__( - f"isort was told to sort imports within code that contains syntax errors: " - f"{file_path}." + f"isort was told to sort imports within code that contains syntax errors: {file_path}." ) self.file_path = file_path diff --git a/isort/output.py b/isort/output.py index 16ebd729..9b72e16c 100644 --- a/isort/output.py +++ b/isort/output.py @@ -339,7 +339,7 @@ def _with_from_imports( ) if comment: single_import_line += ( - f"{(comments and ';') or config.comment_prefix} " f"{comment}" + f"{(comments and ';') or config.comment_prefix} {comment}" ) if from_import in as_imports: if ( @@ -459,8 +459,7 @@ def _with_from_imports( # keep the name in the main list and hoist the comment to the statement. if ( comment.lower().startswith("noqa") - and config.multi_line_output - == wrap.Modes.HANGING_INDENT # type: ignore[attr-defined] + and config.multi_line_output == wrap.Modes.HANGING_INDENT # type: ignore[attr-defined] # noqa: E501 ): comments = list(comments) if comments else [] comments.append(comment) @@ -479,7 +478,7 @@ def _with_from_imports( comment_prefix=config.comment_prefix, ) single_import_line += ( - f"{(use_comments and ';') or config.comment_prefix} " f"{comment}" + f"{(use_comments and ';') or config.comment_prefix} {comment}" ) output.append(wrap.line(single_import_line, parsed.line_separator, config)) @@ -519,8 +518,7 @@ def _with_from_imports( if ( len(import_statement) > config.line_length and len(from_import_section) > 0 - and config.multi_line_output - not in (wrap.Modes.GRID, wrap.Modes.VERTICAL) # type: ignore + and config.multi_line_output not in (wrap.Modes.GRID, wrap.Modes.VERTICAL) # type: ignore # noqa: E501 ): do_multiline_reformat = True diff --git a/isort/parse.py b/isort/parse.py index 170f9d83..2311c06e 100644 --- a/isort/parse.py +++ b/isort/parse.py @@ -460,9 +460,9 @@ def file_contents(contents: str, config: Config = DEFAULT_CONFIG) -> ParsedConte for import_name in just_imports: associated_comment = nested_comments.get(import_name) if associated_comment: - categorized_comments["nested"].setdefault(import_from, {})[ - import_name - ] = associated_comment + categorized_comments["nested"].setdefault(import_from, {})[import_name] = ( + associated_comment + ) if associated_comment in comments: # pragma: no branch comments.pop(comments.index(associated_comment)) if ( diff --git a/isort/wrap_modes.py b/isort/wrap_modes.py index e24bb7a4..cc4a97fd 100644 --- a/isort/wrap_modes.py +++ b/isort/wrap_modes.py @@ -265,7 +265,7 @@ def vertical_hanging_indent_bracket(**interface: Any) -> str: if not interface["imports"]: return "" statement = vertical_hanging_indent(**interface) - return f'{statement[:-1]}{interface["indent"]})' + return f"{statement[:-1]}{interface['indent']})" @_wrap_mode diff --git a/pyproject.toml b/pyproject.toml index ced63879..0e3e0751 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,3 @@ -[tool.black] -line-length = 100 - [project] name = "isort" dynamic = ["version"] diff --git a/scripts/build_profile_docs.py b/scripts/build_profile_docs.py index 8bd3ed97..32f483a8 100755 --- a/scripts/build_profile_docs.py +++ b/scripts/build_profile_docs.py @@ -24,13 +24,13 @@ def format_profile(profile_name: str, profile: dict[str, Any]) -> str: return f""" #{profile_name} -{profile.get('description', '')} +{profile.get("description", "")} {options} """ def document_text() -> str: - return f"{HEADER}{''.join(format_profile(profile_name, profile) for profile_name, profile in profiles.items())}" + return f"{HEADER}{''.join(format_profile(profile_name, profile) for profile_name, profile in profiles.items())}" def write_document(): diff --git a/tests/unit/test_identify.py b/tests/unit/test_identify.py index 7b1e6f97..103e1105 100644 --- a/tests/unit/test_identify.py +++ b/tests/unit/test_identify.py @@ -231,25 +231,22 @@ def test_complex_examples(): == 9 ) assert not imports_in_code("from os import \\") - assert ( - imports_in_code( - """ + assert imports_in_code( + """ from os \\ import ( system""" + ) == [ + Import( + line_number=2, + indented=False, + module="os", + attribute="system", + alias=None, + cimport=False, + file_path=None, ) - == [ - Import( - line_number=2, - indented=False, - module="os", - attribute="system", - alias=None, - cimport=False, - file_path=None, - ) - ] - ) + ] def test_aliases(): diff --git a/tests/unit/test_isort.py b/tests/unit/test_isort.py index b420e470..da4029d8 100644 --- a/tests/unit/test_isort.py +++ b/tests/unit/test_isort.py @@ -76,7 +76,7 @@ def test_happy_path() -> None: test_input = "import sys\nimport os\nimport myproject.test\nimport django.settings" test_output = isort.code(test_input, known_first_party=["myproject"]) assert test_output == ( - "import os\n" "import sys\n" "\n" "import django.settings\n" "\n" "import myproject.test\n" + "import os\nimport sys\n\nimport django.settings\n\nimport myproject.test\n" ) @@ -114,12 +114,10 @@ def test_correct_space_between_imports() -> None: test_output_method = isort.code(test_input_method) assert test_output_method == ("import sys\n\n\ndef my_method():\n print('hello world')\n") - test_input_decorator = ( - "import sys\n" "@my_decorator\n" "def my_method():\n" " print('hello world')\n" - ) + test_input_decorator = "import sys\n@my_decorator\ndef my_method():\n print('hello world')\n" test_output_decorator = isort.code(test_input_decorator) assert test_output_decorator == ( - "import sys\n" "\n" "\n" "@my_decorator\n" "def my_method():\n" " print('hello world')\n" + "import sys\n\n\n@my_decorator\ndef my_method():\n print('hello world')\n" ) test_input_class = "import sys\nclass MyClass(object):\n pass\n" @@ -853,12 +851,7 @@ def test_add_imports() -> None: test_input = "import lib6\nimport lib2\nimport lib5\nimport lib1\n\n" test_output = isort.code(code=test_input, add_imports=["import lib4", "import lib7"]) assert test_output == ( - "import lib1\n" - "import lib2\n" - "import lib4\n" - "import lib5\n" - "import lib6\n" - "import lib7\n" + "import lib1\nimport lib2\nimport lib4\nimport lib5\nimport lib6\nimport lib7\n" ) # Using simplified syntax @@ -875,7 +868,7 @@ def test_add_imports() -> None: ) # On a file that has no pre-existing imports - test_input = '"""Module docstring"""\n' "class MyClass(object):\n pass\n" + test_input = '"""Module docstring"""\nclass MyClass(object):\n pass\n' test_output = isort.code(code=test_input, add_imports=["from __future__ import print_function"]) assert test_output == ( '"""Module docstring"""\n' @@ -888,7 +881,7 @@ def test_add_imports() -> None: # On a file that has no pre-existing imports and a multiline docstring test_input = ( - '"""Module docstring\n\nWith a second line\n"""\n' "class MyClass(object):\n pass\n" + '"""Module docstring\n\nWith a second line\n"""\nclass MyClass(object):\n pass\n' ) test_output = isort.code(code=test_input, add_imports=["from __future__ import print_function"]) assert test_output == ( @@ -906,9 +899,7 @@ def test_add_imports() -> None: # On a file that has no pre-existing imports and a multiline docstring. # In this example, the closing quotes for the docstring are on the final # line rather than a separate one. - test_input = ( - '"""Module docstring\n\nWith a second line"""\n' "class MyClass(object):\n pass\n" - ) + test_input = '"""Module docstring\n\nWith a second line"""\nclass MyClass(object):\n pass\n' test_output = isort.code(code=test_input, add_imports=["from __future__ import print_function"]) assert test_output == ( '"""Module docstring\n' @@ -925,7 +916,7 @@ def test_add_imports() -> None: test_input = "class MyClass(object):\n pass\n" test_output = isort.code(code=test_input, add_imports=["from __future__ import print_function"]) assert test_output == ( - "from __future__ import print_function\n" "\n" "\n" "class MyClass(object):\n" " pass\n" + "from __future__ import print_function\n\n\nclass MyClass(object):\n pass\n" ) # On a file with no content what so ever @@ -946,9 +937,7 @@ def test_remove_imports() -> None: assert test_output == "import lib1\nimport lib5\n" # Using natural syntax - test_input = ( - "import lib6\n" "import lib2\n" "import lib5\n" "import lib1\n" "from lib8 import a" - ) + test_input = "import lib6\nimport lib2\nimport lib5\nimport lib1\nfrom lib8 import a" test_output = isort.code( code=test_input, remove_imports=["import lib2", "import lib6", "from lib8 import a"] ) @@ -983,16 +972,16 @@ def test_explicitly_local_import() -> None: def test_quotes_in_file() -> None: """Ensure imports within triple quotes don't get imported.""" - test_input = "import os\n\n" '"""\n' "Let us\nimport foo\nokay?\n" '"""\n' + test_input = 'import os\n\n"""\nLet us\nimport foo\nokay?\n"""\n' assert isort.code(test_input) == test_input - test_input = "import os\n\n" '\'"""\'\n' "import foo\n" + test_input = 'import os\n\n\'"""\'\nimport foo\n' assert isort.code(test_input) == test_input - test_input = "import os\n\n" '"""Let us"""\n' "import foo\n\n" '"""okay?"""\n' + test_input = 'import os\n\n"""Let us"""\nimport foo\n\n"""okay?"""\n' assert isort.code(test_input) == test_input - test_input = "import os\n\n" '#"""\n' "import foo\n" '#"""' + test_input = 'import os\n\n#"""\nimport foo\n#"""' assert isort.code(test_input) == ('import os\n\nimport foo\n\n#"""\n#"""\n') test_input = "import os\n\n'\\\nimport foo'\n" @@ -1109,14 +1098,14 @@ def test_default_section() -> None: code=test_input, known_third_party=["django"], default_section="FIRSTPARTY" ) assert test_output == ( - "import os\n" "import sys\n" "\n" "import django.settings\n" "\n" "import myproject.test\n" + "import os\nimport sys\n\nimport django.settings\n\nimport myproject.test\n" ) test_output_custom = isort.code( code=test_input, known_third_party=["django"], default_section="STDLIB" ) assert test_output_custom == ( - "import myproject.test\n" "import os\n" "import sys\n" "\n" "import django.settings\n" + "import myproject.test\nimport os\nimport sys\n\nimport django.settings\n" ) @@ -1224,9 +1213,7 @@ def test_force_single_line_imports() -> None: "from third_party import lib22\n" ) - test_input = ( - "from third_party import lib_a, lib_b, lib_d\n" "from third_party.lib_c import lib1\n" - ) + test_input = "from third_party import lib_a, lib_b, lib_d\nfrom third_party.lib_c import lib1\n" test_output = isort.code( code=test_input, multi_line_output=WrapModes.GRID, line_length=40, force_single_line=True ) @@ -1250,9 +1237,7 @@ def test_force_single_line_long_imports() -> None: def test_force_single_line_imports_and_sort_within_sections() -> None: - test_input = ( - "from third_party import lib_a, lib_b, lib_d\n" "from third_party.lib_c import lib1\n" - ) + test_input = "from third_party import lib_a, lib_b, lib_d\nfrom third_party.lib_c import lib1\n" test_output = isort.code( code=test_input, multi_line_output=WrapModes.GRID, @@ -1640,7 +1625,7 @@ def test_multiline_import() -> None: "forced_separate": "asdf", } expected_output = ( - "from pkg import more_stuff\n" "from pkg import other_suff\n" "from pkg import stuff\n" + "from pkg import more_stuff\nfrom pkg import other_suff\nfrom pkg import stuff\n" ) assert isort.code(test_input, **custom_configuration) == expected_output @@ -1769,41 +1754,23 @@ def test_smart_lines_after_import_section() -> None: assert isort.code(test_input) == ("from a import b\n\n\nasync def my_function():\n pass\n") # two spaces if a method or class after imports - even if comment before function - test_input = ( - "from a import b\n" "# comment should be ignored\n" "def my_function():\n" " pass\n" - ) + test_input = "from a import b\n# comment should be ignored\ndef my_function():\n pass\n" assert isort.code(test_input) == ( - "from a import b\n" - "\n" - "\n" - "# comment should be ignored\n" - "def my_function():\n" - " pass\n" + "from a import b\n\n\n# comment should be ignored\ndef my_function():\n pass\n" ) # the same logic does not apply to doc strings test_input = ( - "from a import b\n" - '"""\n' - " comment should be ignored\n" - '"""\n' - "def my_function():\n" - " pass\n" + 'from a import b\n"""\n comment should be ignored\n"""\ndef my_function():\n pass\n' ) assert isort.code(test_input) == ( - "from a import b\n" - "\n" - '"""\n' - " comment should be ignored\n" - '"""\n' - "def my_function():\n" - " pass\n" + 'from a import b\n\n"""\n comment should be ignored\n"""\ndef my_function():\n pass\n' ) # Ensure logic doesn't incorrectly skip over assignments to multi-line strings test_input = 'from a import b\nX = """test\n"""\ndef my_function():\n pass\n' assert isort.code(test_input) == ( - "from a import b\n" "\n" 'X = """test\n' '"""\n' "def my_function():\n" " pass\n" + 'from a import b\n\nX = """test\n"""\ndef my_function():\n pass\n' ) @@ -1867,11 +1834,9 @@ def test_keep_comments() -> None: ) # Test case where imports comments make imports extend pass the line length - test_input = ( - "from a import b # My Comment1\n" "from a import c # My Comment2\n" "from a import d\n" - ) + test_input = "from a import b # My Comment1\nfrom a import c # My Comment2\nfrom a import d\n" assert isort.code(test_input, line_length=45) == ( - "from a import b # My Comment1\n" "from a import c # My Comment2\n" "from a import d\n" + "from a import b # My Comment1\nfrom a import c # My Comment2\nfrom a import d\n" ) # Test case where imports with comments will be beyond line length limit @@ -1890,9 +1855,7 @@ def test_keep_comments() -> None: # Test that 'import ... as ...' comments are not collected inappropriately test_input = ( - "from a import b as bb # b comment\n" - "from a import c as cc # c comment\n" - "from a import d\n" + "from a import b as bb # b comment\nfrom a import c as cc # c comment\nfrom a import d\n" ) assert isort.code(test_input) == test_input assert isort.code(test_input, combine_as_imports=True) == ( @@ -1930,7 +1893,7 @@ def test_include_trailing_comma() -> None: include_trailing_comma=True, ) assert test_output_grid == ( - "from third_party import (lib1, lib2,\n" " lib3, lib4,)\n" + "from third_party import (lib1, lib2,\n lib3, lib4,)\n" ) test_output_vertical = isort.code( @@ -1953,7 +1916,7 @@ def test_include_trailing_comma() -> None: include_trailing_comma=True, ) assert test_output_vertical_indent == ( - "from third_party import (\n" " lib1,\n" " lib2,\n" " lib3,\n" " lib4,\n" ")\n" + "from third_party import (\n lib1,\n lib2,\n lib3,\n lib4,\n)\n" ) test_output_vertical_grid = isort.code( @@ -2165,9 +2128,7 @@ def test_long_line_comments() -> None: def test_tab_character_in_import() -> None: """Ensure isort correctly handles import statements that contain a tab character""" - test_input = ( - "from __future__ import print_function\n" "from __future__ import\tprint_function\n" - ) + test_input = "from __future__ import print_function\nfrom __future__ import\tprint_function\n" assert isort.code(test_input) == "from __future__ import print_function\n" @@ -2430,10 +2391,7 @@ def test_from_first() -> None: def test_top_comments() -> None: """Ensure correct behavior with top comments""" test_input = ( - "# -*- encoding: utf-8 -*-\n" - "# Test comment\n" - "#\n" - "from __future__ import unicode_literals\n" + "# -*- encoding: utf-8 -*-\n# Test comment\n#\nfrom __future__ import unicode_literals\n" ) assert isort.code(test_input) == test_input @@ -2505,22 +2463,15 @@ def test_force_grid_wrap_long() -> None: def test_uses_jinja_variables() -> None: """Test a basic set of imports that use jinja variables""" - test_input = ( - "import sys\n" "import os\n" "import myproject.{ test }\n" "import django.{ settings }" - ) + test_input = "import sys\nimport os\nimport myproject.{ test }\nimport django.{ settings }" test_output = isort.code( code=test_input, known_third_party=["django"], known_first_party=["myproject"] ) assert test_output == ( - "import os\n" - "import sys\n" - "\n" - "import django.{ settings }\n" - "\n" - "import myproject.{ test }\n" + "import os\nimport sys\n\nimport django.{ settings }\n\nimport myproject.{ test }\n" ) - test_input = "import {{ cookiecutter.repo_name }}\n" "from foo import {{ cookiecutter.bar }}\n" + test_input = "import {{ cookiecutter.repo_name }}\nfrom foo import {{ cookiecutter.bar }}\n" assert isort.code(test_input) == test_input @@ -2686,7 +2637,7 @@ def test_shouldnt_add_lines() -> None: """Ensure that isort doesn't add a blank line when a top of import comment is present, See: issue #316 """ - test_input = '"""Text"""\n' "# This is a comment\nimport pkg_resources\n" + test_input = '"""Text"""\n# This is a comment\nimport pkg_resources\n' assert isort.code(test_input) == test_input @@ -2761,7 +2712,7 @@ def test_alphabetic_sorting_no_newlines() -> None: test_output = isort.code(code=test_input, force_alphabetical_sort_within_sections=True) assert test_input == test_output - test_input = "import os\n" "import unittest\n" "\n" "from a import b\n" "\n" "\n" "print(1)\n" + test_input = "import os\nimport unittest\n\nfrom a import b\n\n\nprint(1)\n" test_output = isort.code( code=test_input, force_alphabetical_sort_within_sections=True, lines_after_imports=2 ) @@ -2771,10 +2722,7 @@ def test_alphabetic_sorting_no_newlines() -> None: def test_sort_within_section() -> None: """Test to ensure its possible to force isort to sort within sections""" test_input = ( - "from Foob import ar\n" - "import foo\n" - "from foo import bar\n" - "from foo.bar import Quux, baz\n" + "from Foob import ar\nimport foo\nfrom foo import bar\nfrom foo.bar import Quux, baz\n" ) test_output = isort.code(test_input, force_sort_within_sections=True) assert test_output == test_input @@ -2810,9 +2758,7 @@ def test_sort_within_section() -> None: ) assert test_output == test_input - test_input = ( - "from Foob import ar\n" "import foo\n" "from foo import Quux\n" "from foo import baz\n" - ) + test_input = "from Foob import ar\nimport foo\nfrom foo import Quux\nfrom foo import baz\n" test_output = isort.code( code=test_input, case_sensitive=True, @@ -2826,10 +2772,7 @@ def test_sort_within_section() -> None: def test_sort_within_section_case_honored() -> None: """Ensure isort can do partial case-sensitive sorting in force-sorted sections""" test_input = ( - "import foo\n" - "from foo import bar\n" - "from foo.bar import Quux, baz\n" - "from Foob import ar\n" + "import foo\nfrom foo import bar\nfrom foo.bar import Quux, baz\nfrom Foob import ar\n" ) test_output = isort.code( test_input, force_sort_within_sections=True, honor_case_in_force_sorted_sections=True @@ -2869,9 +2812,7 @@ def test_sort_within_section_case_honored() -> None: ) assert test_output == test_input - test_input = ( - "from Foob import ar\n" "import foo\n" "from foo import Quux\n" "from foo import baz\n" - ) + test_input = "from Foob import ar\nimport foo\nfrom foo import Quux\nfrom foo import baz\n" test_output = isort.code( code=test_input, case_sensitive=True, @@ -3028,7 +2969,7 @@ def test_function_with_docstring() -> None: function with a docstring """ add_imports = ["from __future__ import unicode_literals"] - test_input = "def foo():\n" ' """ Single line triple quoted doctring """\n' " pass\n" + test_input = 'def foo():\n """ Single line triple quoted doctring """\n pass\n' expected_output = ( "from __future__ import unicode_literals\n" "\n" @@ -3120,13 +3061,7 @@ def test_import_inside_class_issue_432() -> None: """ test_input = "# coding=utf-8\nclass Foo:\n def bar(self):\n pass\n" expected_output = ( - "# coding=utf-8\n" - "import baz\n" - "\n" - "\n" - "class Foo:\n" - " def bar(self):\n" - " pass\n" + "# coding=utf-8\nimport baz\n\n\nclass Foo:\n def bar(self):\n pass\n" ) assert isort.code(test_input, add_imports=["import baz"]) == expected_output @@ -3140,13 +3075,13 @@ def test_wildcard_import_without_space_issue_496() -> None: def test_import_line_mangles_issues_491() -> None: """Test to ensure comment on import with parens doesn't cause issues""" - test_input = "import os # ([\n\n" 'print("hi")\n' + test_input = 'import os # ([\n\nprint("hi")\n' assert isort.code(test_input) == test_input def test_import_line_mangles_issues_505() -> None: """Test to ensure comment on import with parens doesn't cause issues""" - test_input = "from sys import * # (\n\n\ndef test():\n" ' print("Test print")\n' + test_input = 'from sys import * # (\n\n\ndef test():\n print("Test print")\n' assert isort.code(test_input) == test_input @@ -3737,12 +3672,7 @@ def test_new_lines_are_preserved() -> None: def test_forced_separate_is_deterministic_issue_774(tmpdir) -> None: config_file = tmpdir.join("setup.cfg") config_file.write( - "[isort]\n" - "forced_separate:\n" - " separate1\n" - " separate2\n" - " separate3\n" - " separate4\n" + "[isort]\nforced_separate:\n separate1\n separate2\n separate3\n separate4\n" ) test_input = ( @@ -3779,9 +3709,7 @@ def test_argument_parsing() -> None: @pytest.mark.parametrize("multiprocess", [False, True]) def test_command_line(tmpdir, capfd, multiprocess: bool) -> None: tmpdir.join("file1.py").write("import re\nimport os\n\nimport contextlib\n\n\nimport isort") - tmpdir.join("file2.py").write( - "import collections\nimport time\n\nimport abc" "\n\n\nimport isort" - ) + tmpdir.join("file2.py").write("import collections\nimport time\n\nimport abc\n\n\nimport isort") arguments = [str(tmpdir), "--settings-path", os.getcwd()] if multiprocess: arguments.extend(["--jobs", "2"]) @@ -3962,10 +3890,7 @@ def test_multiple_as_imports() -> None: assert test_output == "from a import b as b, b as bb, b as bb_\n" test_input = ( - "from a import b\n" - "from a import b as b\n" - "from a import b as bb\n" - "from a import b as bb_\n" + "from a import b\nfrom a import b as b\nfrom a import b as bb\nfrom a import b as bb_\n" ) test_output = isort.code(test_input) assert test_output == test_input @@ -3973,10 +3898,7 @@ def test_multiple_as_imports() -> None: assert test_output == "from a import b, b as b, b as bb, b as bb_\n" test_input = ( - "from a import b as e\n" - "from a import b as c\n" - "from a import b\n" - "from a import b as f\n" + "from a import b as e\nfrom a import b as c\nfrom a import b\nfrom a import b as f\n" ) test_output = isort.code(test_input) assert ( @@ -4032,11 +3954,7 @@ def test_all_imports_from_single_module() -> None: "from a import w, x, y, z\n" ) test_input = ( - "import a\n" - "from a import *\n" - "from a import z, x, y\n" - "from a import b\n" - "from a import w\n" + "import a\nfrom a import *\nfrom a import z, x, y\nfrom a import b\nfrom a import w\n" ) test_output = isort.code( code=test_input, @@ -4116,11 +4034,7 @@ def test_all_imports_from_single_module() -> None: "from a import e as f\n" ) test_input = ( - "import a\n" - "from a import *\n" - "from a import z, x, y\n" - "from a import b\n" - "from a import w\n" + "import a\nfrom a import *\nfrom a import z, x, y\nfrom a import b\nfrom a import w\n" ) test_output = isort.code( code=test_input, @@ -4207,11 +4121,7 @@ def test_all_imports_from_single_module() -> None: "from a import z\n" ) test_input = ( - "import a\n" - "from a import *\n" - "from a import z, x, y\n" - "from a import b\n" - "from a import w\n" + "import a\nfrom a import *\nfrom a import z, x, y\nfrom a import b\nfrom a import w\n" ) test_output = isort.code( code=test_input, @@ -4302,9 +4212,7 @@ def test_to_ensure_empty_line_not_added_to_file_start_issue_889() -> None: def test_to_ensure_correctly_handling_of_whitespace_only_issue_811(capsys) -> None: - test_input = ( - "import os\n" "import sys\n" "\n" "\x0c\n" "def my_function():\n" ' print("hi")\n' - ) + test_input = 'import os\nimport sys\n\n\x0c\ndef my_function():\n print("hi")\n' isort.code(test_input, ignore_whitespace=True) out, err = capsys.readouterr() assert out == "" @@ -4321,14 +4229,14 @@ def test_settings_path_skip_issue_909(tmpdir) -> None: base_dir = tmpdir.mkdir("project") config_dir = base_dir.mkdir("conf") config_dir.join(".isort.cfg").write( - "[isort]\n" "skip =\n" " file_to_be_skipped.py\n" "skip_glob =\n" " *glob_skip*\n" + "[isort]\nskip =\n file_to_be_skipped.py\nskip_glob =\n *glob_skip*\n" ) base_dir.join("file_glob_skip.py").write( - "import os\n\n" 'print("Hello World")\n' "\nimport sys\nimport os\n" + 'import os\n\nprint("Hello World")\n\nimport sys\nimport os\n' ) base_dir.join("file_to_be_skipped.py").write( - "import os\n\n" 'print("Hello World")' "\nimport sys\nimport os\n" + 'import os\n\nprint("Hello World")\nimport sys\nimport os\n' ) test_run_directory = os.getcwd() @@ -4358,11 +4266,11 @@ def test_skip_paths_issue_938(tmpdir) -> None: "skip_glob =\n" " migrations/**.py\n" ) - base_dir.join("dont_skip.py").write("import os\n\n" 'print("Hello World")' "\nimport sys\n") + base_dir.join("dont_skip.py").write('import os\n\nprint("Hello World")\nimport sys\n') migrations_dir = base_dir.mkdir("migrations") migrations_dir.join("file_glob_skip.py").write( - "import os\n\n" 'print("Hello World")\n' "\nimport sys\n" + 'import os\n\nprint("Hello World")\n\nimport sys\n' ) test_run_directory = os.getcwd() @@ -4395,9 +4303,7 @@ def test_skip_paths_issue_938(tmpdir) -> None: def test_failing_file_check_916() -> None: test_input = ( - "#!/usr/bin/env python\n" - "# -*- coding: utf-8 -*-\n" - "from __future__ import unicode_literals\n" + "#!/usr/bin/env python\n# -*- coding: utf-8 -*-\nfrom __future__ import unicode_literals\n" ) expected_output = ( "#!/usr/bin/env python\n" @@ -4466,9 +4372,9 @@ def test_isort_keeps_comments_issue_691() -> None: def test_isort_multiline_with_tab_issue_1714() -> None: - test_input = "from sys \\ \n" "\timport version\n" "print(version)\n" + test_input = "from sys \\ \n\timport version\nprint(version)\n" - expected_output = "from sys import version\n" "\n" "print(version)\n" + expected_output = "from sys import version\n\nprint(version)\n" assert isort.code(test_input) == expected_output @@ -5480,20 +5386,18 @@ def test_only_sections() -> None: def test_combine_straight_imports() -> None: """Tests to ensure that combine_straight_imports works correctly""" - test_input = ( - "import os\n" "import sys\n" "# this is a comment\n" "import math # inline comment\n" - ) + test_input = "import os\nimport sys\n# this is a comment\nimport math # inline comment\n" assert isort.code(test_input, combine_straight_imports=True) == ( - "# this is a comment\n" "import math, os, sys # inline comment\n" + "# this is a comment\nimport math, os, sys # inline comment\n" ) # test to ensure that combine_straight_import works with only_sections - test_input = "import sys, os\n" "import a\n" "import math\n" "import b\n" + test_input = "import sys, os\nimport a\nimport math\nimport b\n" assert isort.code(test_input, combine_straight_imports=True, only_sections=True) == ( - "import sys, os, math\n" "\n" "import a, b\n" + "import sys, os, math\n\nimport a, b\n" ) @@ -5550,7 +5454,7 @@ def seek(self, offset: int, whence: int = os.SEEK_SET, /) -> int: def seekable(self): return False - test_input = NonSeekableTestStream("import m2\n" "import m1\n" "not_import = 7") + test_input = NonSeekableTestStream("import m2\nimport m1\nnot_import = 7") identified_imports = list(map(str, api.find_imports_in_stream(test_input))) assert identified_imports == [":1 import m2", ":2 import m1"] diff --git a/tests/unit/test_main.py b/tests/unit/test_main.py index 8689ca31..65c5aa60 100644 --- a/tests/unit/test_main.py +++ b/tests/unit/test_main.py @@ -1050,12 +1050,12 @@ def test_only_modified_flag(tmpdir, capsys): def test_identify_imports_main(tmpdir, capsys): - file_content = "import mod2\nimport mod2\n" "a = 1\n" "import mod1\n" + file_content = "import mod2\nimport mod2\na = 1\nimport mod1\n" some_file = tmpdir.join("some_file.py") some_file.write(file_content) file_imports = f"{some_file}:1 import mod2\n{some_file}:4 import mod1\n" file_imports_with_dupes = ( - f"{some_file}:1 import mod2\n{some_file}:2 import mod2\n" f"{some_file}:4 import mod1\n" + f"{some_file}:1 import mod2\n{some_file}:2 import mod2\n{some_file}:4 import mod1\n" ) main.identify_imports_main([str(some_file), "--unique"]) diff --git a/tests/unit/test_regressions.py b/tests/unit/test_regressions.py index 1d97fa5a..719357ae 100644 --- a/tests/unit/test_regressions.py +++ b/tests/unit/test_regressions.py @@ -495,7 +495,7 @@ def test_windows_diff_too_large_misrepresentative_issue_1348(test_path): isort.file(test_path / "example_crlf_file.py", show_diff=diff_output) diff_output.seek(0) assert diff_output.read().endswith( - "-1,5 +1,5 @@\n+import a\r\n import b\r\n" "-import a\r\n \r\n \r\n def func():\r\n" + "-1,5 +1,5 @@\n+import a\r\n import b\r\n-import a\r\n \r\n \r\n def func():\r\n" ) @@ -1169,9 +1169,8 @@ def test_isort_float_to_top_correctly_identifies_single_line_comments_1499(): one line. See: https://github.com/PyCQA/isort/issues/1499 """ - assert ( - isort.code( - '''#!/usr/bin/env bash + assert isort.code( + '''#!/usr/bin/env bash """My comment""" def foo(): pass @@ -1181,10 +1180,9 @@ def foo(): def bar(): pass ''', - float_to_top=True, - ) - == ( - '''#!/usr/bin/env bash + float_to_top=True, + ) == ( + '''#!/usr/bin/env bash """My comment""" import a @@ -1196,11 +1194,9 @@ def foo(): def bar(): pass ''' - ) ) - assert ( - isort.code( - """#!/usr/bin/env bash + assert isort.code( + """#!/usr/bin/env bash '''My comment''' def foo(): pass @@ -1210,10 +1206,9 @@ def foo(): def bar(): pass """, - float_to_top=True, - ) - == ( - """#!/usr/bin/env bash + float_to_top=True, + ) == ( + """#!/usr/bin/env bash '''My comment''' import a @@ -1225,7 +1220,6 @@ def foo(): def bar(): pass """ - ) ) assert isort.check_code( diff --git a/tox.ini b/tox.ini index 2f64c975..5ab5b7c9 100644 --- a/tox.ini +++ b/tox.ini @@ -55,11 +55,11 @@ dependency_groups = commands = cruft check mypy -p isort -p tests - black --target-version py310 --check . isort --profile hug --check --diff isort/ tests/ isort --profile hug --check --diff example_isort_formatting_plugin/ isort --profile hug --check --diff example_isort_sorting_plugin/ isort --profile hug --check --diff example_shared_isort_profile/ flake8 isort/ tests/ ruff check + ruff format --check bandit -r isort/ -x isort/_vendored