ruff icon indicating copy to clipboard operation
ruff copied to clipboard

Feature: Support isort multi_line_output option

Open mikelane opened this issue 2 years ago • 14 comments

The isort module provides many different ways of accomplishing the wrapping for a given project. From my experience, this is a widely used option in projects that use isort, so it would be nice to have this support in ruff.

Ideally, the ruff setting would be something like this:

[tool.ruff.isort]
multi_line_output = 3  # Vertical Hanging Indent

The output options would follow the options settings and option values listed in the isort documentation.

mikelane avatar Feb 06 '23 01:02 mikelane

If we're re-engineering this, a compact grid mode would be really nice. That is, try:

  • putting everything on one line,
  • grid, and
  • hanging grid.

Choose the one with the fewest lines that fit within the maximum line width. I contributed something like this for isort. But that contribution only bumps to hanging grid when grid is impossible. It would be nice to also bump when hanging grid is shorter.

(Also, just my opinion, but mode 2 that uses line continuation \ should probably be deprecated?)

NeilGirdhar avatar Feb 16 '23 22:02 NeilGirdhar

We need multi_line_output=5 (vert-grid-grouped).

spaceone avatar Apr 14 '23 04:04 spaceone

Same, we'd have moved from isort to ruff if it supported multi_line_output=5.

nicwolff avatar May 02 '23 16:05 nicwolff

Thinking about this more, I would like to see the options in Ruff be something like:

imports_allow_grid = true
imports_allow_vertical = true
imports_parenthesis_on_newline = false

Then the most common ISort modes correspond to:

  • 0: (true, true, false)
  • 1: (false, true, false)
  • 3: (false, false, true)
  • 4: (true, false, false)
  • 5: (true, false, true)

And add an option to imports_choose_shortest that chooses the shortest representation allowed that fits the options. So just be cause you chose (true, true, false), doesn't mean that it should do somethign crazy like:

from alksdjflks_flaksjdflkajsdfljka_laskjdf_alksjdf_alksjdflaskd_skldj import (some_symbol,
                                                                               some_other_symbol,
                                                                               some_third_symbol,
                                                                               some_fourth_symbol)
# Instead:
from alksdjflks_flaksjdflkajsdfljka_laskjdf_alksjdf_alksjdflaskd_skldj import (
    some_symbol, some_other_symbol, some_third_symbol, some_fourth_symbol)

I'd love to stop using isort, but I don't want to lose my nice imports.

NeilGirdhar avatar Aug 08 '23 21:08 NeilGirdhar

Would love to see support for multi_line_output=0, can't ditch isort until that's available :)

ThiefMaster avatar Nov 13 '23 22:11 ThiefMaster

@ThiefMaster That's the one I'm waiting for too. But really, what we need is for Ruff to support both vertical and grid formatting. If we had that, we would have it in the code and the imports.

NeilGirdhar avatar Nov 13 '23 23:11 NeilGirdhar

I used to use black, ruff and isort to format my code. Now I just use ruff and isort.

When ruff supports multi_line_output=3 I'll be able to just use ruff.

Until such time... I'll continue to monitor this issue 😜

dhirschfeld avatar Nov 13 '23 23:11 dhirschfeld

@dhirschfeld, wait a second. The default formatting behavior is multi_line_output=3, right? It is the vertical hanging indent mode. Am I missing something? I briefly tested it against isort and saw no difference.

Full disclosure: I started working on this feature yesterday since I have some time and attention to spare, but I don’t want to promise anything yet.

Aeron avatar Nov 24 '23 12:11 Aeron

I understand that we have different preferences when it comes to formatting code. Black and ruff's formatter have sofar been leaning towards opinionated formatting with few options whereas Ruff's linter is extremely configurable. Ruff's isort is somewhere in between. I believe @charliermarsh expressed once that he intentionally didn't implement all isort options and we're considering making isort its own tool or integrating it into the formatter. This is why I think we should be very deliberate about supporting new isort options that are incompatible with the formatter because we either need to deprecate them again in the future, or they force us to change the direction of the formatter.

MichaReiser avatar Nov 27 '23 02:11 MichaReiser

nd we're considering making isort its own tool or integrating it into the formatter.

I think integrating it into the formatter makes perfect sense. After all, all of these "isort modes" that people are discussing are actually special cases of various formatter output preferences. Ruff currently supports only three output types (single line, hanging single line, and hanging multi-line).

This is why I think we should be very deliberate about supporting new isort options

I agree. I think it makes sense for the import statement formatting to be consistent with code formatting. Therefore, I don't think there should be any isort options at all. What we are really asking for is generalization of the formatter. I understand that that may not be a priority today, but hopefully it will come eventually.

NeilGirdhar avatar Nov 27 '23 03:11 NeilGirdhar

I had an idea those two could be separate things. The new built-in formatter may have a few opinionated options to organize imports or none at all, and the ruff-isort formatter can be its own thing for people who want a backward-compatible way of doing it.

But yeah, you’re right—formatting kicks after the import organization and ruins the latter if the result is incompatible with those three output types. So the option I described above only would work if users of ruff-isort ditch the new formatter, which is highly unlikely, considering everybody wants a complete package.

I’m good with the current vertical hanging indent approach since I’m using it anyway. But people want grids. Yet meddling with the new formatter is a different beast than adding support for isort modes separately.

Ok, I put my implementation on pause then. It’ll wait until a decision.

Aeron avatar Nov 27 '23 14:11 Aeron

I believe this would also benefit RUF022:

__all__ = [
    "a", "b", "c",
]

nineteendo avatar Feb 10 '24 14:02 nineteendo

I understand that we have different preferences when it comes to formatting code. Black and ruff's formatter have sofar been leaning towards opinionated formatting with few options whereas Ruff's linter is extremely configurable. Ruff's isort is somewhere in between. I believe @charliermarsh expressed once that he intentionally didn't implement all isort options and we're considering making isort its own tool or integrating it into the formatter. This is why I think we should be very deliberate about supporting new isort options that are incompatible with the formatter because we either need to deprecate them again in the future, or they force us to change the direction of the formatter.

As someone who is currently uninterested in the formatter, but interested in the linter, I would be happy if ruff check --select I supported all isort modes (mode 5 for me personally), and don't have an opinion on whether ruff format should.

Maybe it could raise a fatal error that says those modes aren't allowed in the formatter?

eli-schwartz avatar Feb 22 '24 19:02 eli-schwartz

I would love to see this feature added as well. A lack of mode 5 support is pretty much the only thing preventing me from using ruff. The current formatting option for imports is incredibly wasteful for code with a lot of short imports in few modules, like my Qt5-based project where you import a lot of GUI components in every file.

vkbo avatar Apr 24 '24 10:04 vkbo