diff --git a/isort/parse.py b/isort/parse.py index e1b20576..3efa2b83 100644 --- a/isort/parse.py +++ b/isort/parse.py @@ -38,17 +38,18 @@ def _infer_line_separator(contents: str) -> str: return "\n" +_FROM_ABSOLUTE_NORMALIZER_PATTERN = re.compile(r"from[\t ]+(.+?)[\t ]+(c?import)[\t ]+") +_FROM_RELATIVE_NORMALIZER_PATTERN = re.compile(r"from[\t ]*(\.+[^\t ]*?)[\t ]*(c?import)[\t ]+") + + 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 = 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 = _FROM_ABSOLUTE_NORMALIZER_PATTERN.sub(r"from \g<1> \g<2> ", raw_line) + line = _FROM_RELATIVE_NORMALIZER_PATTERN.sub(r"from \g<1> \g<2> ", line) line = line.replace("import*", "import *") - 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 diff --git a/tests/unit/test_parse.py b/tests/unit/test_parse.py index 6b0d9be9..804f7f40 100644 --- a/tests/unit/test_parse.py +++ b/tests/unit/test_parse.py @@ -95,13 +95,13 @@ def test_fuzz_skip_line(line, in_quote, index, section_comments, needs_import): ("from..import a", "from .. import a"), ("import *", "import *"), ("import*", "import *"), - ("from . import a", "from . import a"), # noqa: PT014 ("from .import a", "from . import a"), ("from ..import a", "from .. import a"), - ("from . cimport a", "from . cimport a"), # noqa: PT014 ("from .cimport a", "from . cimport a"), ("from ..cimport a", "from .. cimport a"), - ("from\t.\timport a", "from . import a"), + ("from\t\t.\t\timport\t\ta", "from . import a"), + ("from \t __future__ \t import \t annotations", "from __future__ import annotations"), + ("from..x import y", "from ..x import y"), ], ) def test_normalize_line(raw_line, expected):