Skip to content

Commit

Permalink
Added a fix for normalizing imports from more than one level of paren…
Browse files Browse the repository at this point in the history
…t modules (issue/2152)
  • Loading branch information
bp72 committed Dec 9, 2023
1 parent 9f7e0e5 commit 15e5bd1
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 9 deletions.
4 changes: 2 additions & 2 deletions isort/identify.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from pathlib import Path
from typing import Iterator, NamedTuple, Optional, TextIO, Tuple

from isort.parse import _normalize_line, _strip_syntax, skip_line
from isort.parse import _strip_syntax, normalize_line, skip_line

from .comments import parse as parse_comments
from .settings import DEFAULT_CONFIG, Config
Expand Down Expand Up @@ -84,7 +84,7 @@ def imports(
statements[-1] = f"{statements[-1]}#{end_of_line_comment[0]}"

for statement in statements:
line, _raw_line = _normalize_line(statement)
line, _raw_line = normalize_line(statement)
if line.startswith(("import ", "cimport ")):
type_of_import = "straight"
elif line.startswith("from "):
Expand Down
15 changes: 8 additions & 7 deletions isort/parse.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Defines parsing functions used by isort for parsing import definitions"""
import re
from collections import OrderedDict, defaultdict
from functools import partial
from itertools import chain
Expand Down Expand Up @@ -36,18 +37,18 @@ def _infer_line_separator(contents: str) -> str:
return "\n"


def _normalize_line(raw_line: str) -> Tuple[str, str]:
def normalize_line(raw_line: str) -> Tuple[str, str]:
"""Normalizes import related statements in the provided line.
Returns (normalized_line: str, raw_line: str)
"""
line = raw_line.replace("from.import ", "from . import ")
line = line.replace("from.cimport ", "from . cimport ")
line = re.sub(r"from(\.+)cimport ", r"from \g<1> cimport ", raw_line)
line = re.sub(r"from(\.+)import ", r"from \g<1> import ", line)
line = line.replace("import*", "import *")
line = line.replace(" .import ", " . import ")
line = line.replace(" .cimport ", " . cimport ")
line = re.sub(r" (\.+)import ", r" \g<1> import ", line)
line = re.sub(r" (\.+)cimport ", r" \g<1> cimport ", line)
line = line.replace("\t", " ")
return (line, raw_line)
return line, raw_line


def import_type(line: str, config: Config = DEFAULT_CONFIG) -> Optional[str]:
Expand Down Expand Up @@ -263,7 +264,7 @@ def file_contents(contents: str, config: Config = DEFAULT_CONFIG) -> ParsedConte
statements[-1] = f"{statements[-1]}#{end_of_line_comment[0]}"

for statement in statements:
line, raw_line = _normalize_line(statement)
line, raw_line = normalize_line(statement)
type_of_import = import_type(line, config) or ""
raw_lines = [raw_line]
if not type_of_import:
Expand Down
27 changes: 27 additions & 0 deletions tests/unit/test_parse.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import pytest
from hypothesis import given
from hypothesis import strategies as st

Expand Down Expand Up @@ -81,3 +82,29 @@ def test_fuzz_skip_line(line, in_quote, index, section_comments, needs_import):
section_comments=section_comments,
needs_import=needs_import,
)


@pytest.mark.parametrize(
"raw_line, expected",
(
("from . cimport a", "from . cimport a"),
("from.cimport a", "from . cimport a"),
("from..cimport a", "from .. cimport a"),
("from . import a", "from . import a"),
("from.import a", "from . import a"),
("from..import a", "from .. import a"),
("import *", "import *"),
("import*", "import *"),
("from . import a", "from . import a"),
("from .import a", "from . import a"),
("from ..import a", "from .. import a"),
("from . cimport a", "from . cimport a"),
("from .cimport a", "from . cimport a"),
("from ..cimport a", "from .. cimport a"),
("from\t.\timport a", "from . import a"),
),
)
def test_normalize_line(raw_line, expected):
line, returned_raw_line = parse.normalize_line(raw_line)
assert line == expected
assert returned_raw_line == raw_line

0 comments on commit 15e5bd1

Please sign in to comment.