PyCQA / PyCQA/isort

`--fss` may lead to incorrect import separation for mixed multi-line and alias imports

Open
#2,455 10 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Python
Stars
7k
Forks
687
Avg merge
4h 56m
Merged PRs (30d)
2

Description

When using --force-sort-within-sections (--fss), imports from the same module can be incorrectly separated.

Reproduction (repro.py):

from module import (
    AAAAAAAAAAAAAAAAAAAAAAAAAA,
    BBBBBBBBBBBBBBBBBBBBBBBBBB,
    CCCCCCCCCCCCCCCCCCCCCCCCCC,
)
from module import DDDDDDDDDDDDDDDDDDDDDDDDDD as d
from module import (
    EEEEEEEEEEEEEEEEEEEEEEEEEE,
    FFFFFFFFFFFFFFFFFFFFFFFFFF,
    GGGGGGGGGGGGGGGGGGGGGGGGGG,
)

Sorting this file with isort repro.py --fss results in imports from the same module being split in a seemingly meaningless way:

from module import (
    AAAAAAAAAAAAAAAAAAAAAAAAAA,
    BBBBBBBBBBBBBBBBBBBBBBBBBB,
    CCCCCCCCCCCCCCCCCCCCCCCCCC,
)
from module import (
    EEEEEEEEEEEEEEEEEEEEEEEEEE,
    FFFFFFFFFFFFFFFFFFFFFFFFFF,
    GGGGGGGGGGGGGGGGGGGGGGGGGG,
)
from module import DDDDDDDDDDDDDDDDDDDDDDDDDD as d

This happens because _with_from_imports sees those as three separate groups, and then during within-section sorting sorting.section_key determines that import (... should precede import D....

It's hard to say that isort is doing something wrong, but splitting imports from the same module is undesirable. My preferred output in this situation would be:

from module import (
    AAAAAAAAAAAAAAAAAAAAAAAAAA,
    BBBBBBBBBBBBBBBBBBBBBBBBBB,
    CCCCCCCCCCCCCCCCCCCCCCCCCC,
    EEEEEEEEEEEEEEEEEEEEEEEEEE,
    FFFFFFFFFFFFFFFFFFFFFFFFFF,
    GGGGGGGGGGGGGGGGGGGGGGGGGG,
)
from module import DDDDDDDDDDDDDDDDDDDDDDDDDD as d

I think there are a few ways to approach this:

  • Add a new configuration option: Introduce a flag (e.g., --force-separate-as-imports) that operates within the _with_from_imports function to explicitly place as_imports at the end of the list.
  • Normalize ( in section_key: Modify the key generation so that module import (AAAA is treated as module import AAAA for sorting purposes. This would not produce my "preferred output," but it would at least leave repro.py unchanged, avoiding multiple separated from module import ( blocks.
  • No new flag, no new sort logic, just merge outputs from new_section_output: Iterate over the new section output, parse them again, and merge imports where possible. I personally think this would be the least preferred option because it doesn't integrate well with the rest of the system and would have a high maintenance cost.

I would appreciate any input from the maintainers on whether this is worth addressing and, if so, which approach is preferred. I am happy to contribute a PR if the team agrees on a direction.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with isort/output.py, especially _with_from_imports, new_section_output, and sorting.section_key, then reproduce the behavior using the supplied repro.py and isort repro.py --fss command. Review the proposed approaches before choosing one; done means imports from the same module are not split into multiple parenthesized blocks while alias imports retain the intended ordering.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
tooling
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
38/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.