Skip to content

Commit 981685b

Browse files
committed
style: add isort plugin to sort imports with the desired style
Sort imports by length, imported objects naturally.
1 parent be4e811 commit 981685b

File tree

4 files changed

+92
-0
lines changed

4 files changed

+92
-0
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,4 @@ wheelhouse/
2323
/psycopg_c/build/
2424
/psycopg_pool/build/
2525
/tools/build/pg_config_vcpkg_stub/build/
26+
/tools/isort-psycopg/build/

tools/isort-psycopg/README.rst

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
Psycopg style isort
2+
===================
3+
4+
This is an isort_ plugin to sort:
5+
6+
- import in length order
7+
- import lists in natural order
8+
9+
The effect is the same of specifying ``--length-sort`` but only for the module
10+
names. For example::
11+
12+
from ccc import aaaa, bbb, cc
13+
from bbbb import ddd, ee
14+
from aaaaa import fff, gg
15+
16+
Example configuration::
17+
18+
[tool.isort]
19+
profile = "black"
20+
length_sort = true
21+
multi_line_output = 9
22+
sort_order = "psycopg"
23+
24+
Note: because this is the first day I use isort at all, there is a chance that
25+
this plug-in is totally useless and the same can be done using isort features.
26+
27+
.. _isort: https://pycqa.github.io/isort/

tools/isort-psycopg/isort_psycopg.py

+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
"""isort function to sort module names by length, objects naturally."""
2+
3+
from __future__ import annotations
4+
5+
import re
6+
import inspect
7+
from typing import Any, Callable, Iterable
8+
9+
from isort.sorting import naturally
10+
11+
12+
def psycosort(
13+
to_sort: Iterable[str],
14+
key: Callable[[str], Any] | None = None,
15+
reverse: bool = False,
16+
) -> list[str]:
17+
# Sniff whether we are sorting an import list (from module import a, b, c)
18+
# or a list of modules.
19+
# Tested with isort 6.0. It might break in the future!
20+
is_from_import = any(
21+
f for f in inspect.stack() if f.function == "_with_from_imports"
22+
)
23+
24+
new_key: Callable[[str], Any] | None
25+
if is_from_import:
26+
if key:
27+
old_key = key
28+
29+
def new_key(s: str) -> Any:
30+
return drop_length(old_key(s))
31+
32+
else:
33+
new_key = drop_length
34+
else:
35+
new_key = key
36+
37+
return naturally(to_sort, key=new_key, reverse=reverse)
38+
39+
40+
def drop_length(s: str) -> Any:
41+
"""Drop the length prefix from the objects sorted."""
42+
return re.sub(r"\d+:", "", s) if s else s

tools/isort-psycopg/pyproject.toml

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
[build-system]
2+
requires = ["setuptools", "wheel"]
3+
build-backend = "setuptools.build_meta"
4+
5+
[project]
6+
name = "isort-psycopg"
7+
description = "isort plug-in to sort imports by module length first"
8+
# Note: to release a new version:
9+
# python -m build -o dist --wheel .
10+
# twine upload dist/isort_psycopg-*-py3-none-any.whl
11+
version = "0.0.1"
12+
13+
[project.readme]
14+
file = "README.rst"
15+
content-type = "text/x-rst"
16+
17+
[[project.authors]]
18+
name = "Daniele Varrazzo"
19+
20+
21+
[project.entry-points."isort.sort_function"]
22+
psycopg = "isort_psycopg:psycosort"

0 commit comments

Comments
 (0)