astral-sh/ruff

Different import sorting order between isort and ruff if import is aliased.

ghuls opened this issue · 13 comments

ghuls commented

Differnt import sorting order between isort and ruff if import is aliased.

# isort --profile=black input.py
$ cat /tmp/isorted_output.py
from numpy import cos, int8, int16, int32, int64
from numpy import sin as np_sin
from numpy import tan, uint8, uint16, uint32, uint64

$ ruff --select I001 --ignore F401 --fix input.py
$ cat /tmp/ruff_isorted_output.py
from numpy import cos, int8, int16, int32, int64, tan, uint8, uint16, uint32, uint64
from numpy import sin as np_sin

Good call, thank you.

ghuls commented

Personally I like the ruff behavior more than the isort behavior. So I hope isort changes their behavior.

I get a completely different sorting when using isort and ruff. In my project, isort file.py gives me:

from abc import abstractmethod
from contextlib import contextmanager

from numpy import concatenate, int32, zeros
from traits.api import Dict, Float, Str, cached_property

import tapy.core.config as config
from tapy.core.base import BasicObject

whereas ruff --select I001 --ignore F401 --fix file.py gives me

from abc import abstractmethod
from contextlib import contextmanager

import tapy.core.config as config
from numpy import concatenate, int32, zeros
from tapy.core.base import BasicObject
from traits.api import Dict, Float, Str, cached_property

Any idea what is going on here? I don't think it is an issue with my config.

It looks like it’s not registering tapy as a first-party module. Would you mind posting your pyproject.toml and project structure?

It looks like it’s not registering tapy as a first-party module. Would you mind posting your pyproject.toml and project structure?

Hi. Thanks for the swift reply! Sure thing, I have a src structure, so submodules are contained in src/tapy/submodule with __init__.py in tapy and submodule directories. The relevant part of my pyproject.toml is

[project]
name = "tapy"
...
requires-python = ">=3.9"
...
dependencies = [
    "tqdm",
    "traits"
]

[project.optional-dependencies]
dev = [
    "ipython",
    "pre-commit",
    "ruff",
    "sphinx",
    "sphinx-autoapi",
    "nbsphinx",
    "sphinx-rtd-theme",
    "sphinx-gallery"
]

[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"

[tool.ruff]
ignore = [
    "D100", "D101", "D102", "D103", "D104", "D105", "D107",
    "D203", "D213",
    "B905",
    "F401",
    "N806"]
line-length = 120
select = ["B", "D", "E", "F", "I", "N", "Q", "W"]

[tool.ruff.flake8-quotes]
inline-quotes = "single"

[tool.ruff.pydocstyle]
convention = "numpy"

Can you try adding the following?

[tool.ruff]
src = ["src"]

(By default, we use src = ["."] which wouldn't pick up your modules.)

OK, so I just found the section in the readme regarding known-first-party modules with tool.ruff.isort which I have not set. However, now everything works without setting src nor known-first-party which is very peculiar.

Thanks for helping out. I don't want to hijack this issue. If I encounter this problem again, I will give an update. For now, it seems to 'just work again'...

(Is it possible you were missing an __init__.py somewhere? Feel free to file another issue if you have any follow-ups :))

Yes, exactly I just found it out, too. I had an __init__.py in src that produces that behaviour without setting src.

So either no __init__.py in src or setting src = ["src"] works correctly. Thanks a lot. Sorry for the clutter, I thought this was related due to the import alias.

No prob at all, glad it’s resolved!

I added a note on this to the docs. I think I view this as a known, but acceptable deviation for now.