astral-sh / ruff

An extremely fast Python linter and code formatter, written in Rust.
https://docs.astral.sh/ruff
MIT License
28.83k stars 934 forks source link

add force-alphabetical-sort-within-sections flag to isort settings #4670

Open alexdauenhauer opened 1 year ago

alexdauenhauer commented 1 year ago

~While I personally like isort better, my company uses reorder-python-imports so I am wondering if there is already support for this and I missed it in the docs, or if support could be added? I am loving this package and would love to have it auto-run the import sorting in the format I need.~

Actually I think it is better to just add force-alphabetical-sort-within-sections flag to isort settings

alexdauenhauer commented 1 year ago

actually it turns out I can almost achieve the same functionality, but the isort arg that I need is force-alphabetical-sort-within-sections and ruff does not yet support this

JonathanPlasse commented 1 year ago

Can you share the configuration? A profile reporder-python-imports could be added.

alexdauenhauer commented 1 year ago

well now I think what would actually be better than adding support for reorder-python-imports, would be to just add the force-alphabetical-sort-within-sections flag for available isort args. I think isort can do everything that reorder-python-imports can do, but not all the flags for isort are available to enable that functionality

sanmai-NL commented 1 year ago

@alexdauenhauer Does this solve it: https://beta.ruff.rs/docs/settings/#isort-force-sort-within-sections?

alexdauenhauer commented 1 year ago

@sanmai-NL unfortunately not. The sorting rules are slightly different. sort-within-sections prioritizes case over alphanumeric (e.g. MY_CONSTANT will be sorted on top of alphabetical_method)

perezzini commented 11 months ago

Any updates about this? Thanks!

owenlamont commented 8 months ago

I'd like this too, I'm trying to get Ruff adopted where I work but this is one area where a lot of code gets formatted differently to our current isort configuration.

owenlamont commented 8 months ago

Update: Actually I don't think this is an issue anymore. Once I noticed the case-sensitive argument which I set to false and I fixed and tweaked some other ruff configuration I was able to exactly reproduce my old isort configuration sorting behaviour that had force_alphabetical_sort_within_sections set to true.

Pierre-Sassoulas commented 5 months ago

@owenlamont do you mind sharing your configuration to mimic force_alphabetical_sort_within_sections, please ? I didn't manage to recreate it from the description.

owenlamont commented 5 months ago

Hi @Pierre-Sassoulas - this was my Ruff isort config taken from my pyproject.toml (note I excluded known-first-party and known-third-party modules which will be specific to your repo). This sorting was close to but not quite identical to isort. I think there were some minor differences with Ruff sorting on full relative import paths (which I personally liked) - I think the difference was something like that - I don't exactly remember but most of the time the import sort order came out identical to how we had isort configured.

[tool.ruff.isort]
case-sensitive = false
combine-as-imports = true
force-sort-within-sections = true
known-first-party = []
known-third-party = []
lines-after-imports = 2
order-by-type = false
section-order = [
    "future",
    "standard-library",
    "third-party",
    "first-party",
    "local-folder"
]

This closely matched the behaviour of the old isort config:

[tool.isort]
profile = "black"
multi_line_output = 3
force_sort_within_sections = true
force_alphabetical_sort_within_sections = true
sections = ["FUTURE", "STDLIB", "THIRDPARTY", "FIRSTPARTY", "LOCALFOLDER"]
known_first_party = []
known_thirdparty = []
skip_gitignore=true
lines_after_imports=2
combine_as_imports=true
Pierre-Sassoulas commented 5 months ago

It's working, thank you a lot @owenlamont !

The sorting rules are slightly different. sort-within-sections prioritizes case over alphanumeric (e.g. MY_CONSTANT will be sorted on top of alphabetical_method)

The specific option that fix this is order-by-type = false.

I guess the issue can be closed then.

Jari27 commented 4 months ago

I have a similar problem that I cannot seem to solve with the current settings on v0.2.1 (although I cannot find anything in the changelogs that indicate this was solved in v0.2.2 or v0.3.0).

I have the following 5 imports:

from pyspark.sql import Column, DataFrame
from pyspark.sql import functions as F
from pyspark.sql import SparkSession
from pyspark.sql import types as T

These are sorted by isort with the following config:

[tool.isort]
line_length = 120
multi_line_output = 3
force_alphabetical_sort_within_sections = "True"
force_sort_within_sections = "False"
profile = "black"

I cannot seem to get the same behaviour with ruff, as it always combines the first and third line into this:

from pyspark.sql import Column, DataFrame, SparkSession
from pyspark.sql import functions as F
from pyspark.sql import types as T

with the following config:

[tool.ruff.lint.isort]
force-sort-within-sections = false
order-by-type = false
case-sensitive = false

Am I misconfiguring anything? It seems like the alphabetical sort is sorting AFTER grouping, instead of before. And I cannot seem to turn this off.

samdoran commented 2 months ago

@Jari27 I think you want force-single-line = true.

from pyspark.sql import Column
from pyspark.sql import DataFrame
from pyspark.sql import functions as F
from pyspark.sql import SparkSession
from pyspark.sql import types as T
Jari27 commented 2 months ago

@samdoran Thanks, that is a lot closer but still not fully compatible. isort (isort==5.10.1) instead puts Column and DataFrame on the same line.

charliermarsh commented 2 months ago

Yes we don't support that.

charliermarsh commented 2 months ago

It's intentional and documented here: https://docs.astral.sh/ruff/faq/#how-does-ruffs-import-sorting-compare-to-isort

Jari27 commented 2 months ago

Ah that's fair. Not sure how I missed it! Thanks for the help!