From: Daniele Varrazzo Date: Wed, 12 Feb 2025 12:26:40 +0000 (+0100) Subject: style: add isort plugin to sort imports with the desired style X-Git-Tag: 3.3.0.dev1~116^2~3 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=981685b06c34b0dac5d13bc102f063d21ecbaa96;p=thirdparty%2Fpsycopg.git style: add isort plugin to sort imports with the desired style Sort imports by length, imported objects naturally. --- diff --git a/.gitignore b/.gitignore index f7ba03c71..7040b9751 100644 --- a/.gitignore +++ b/.gitignore @@ -23,3 +23,4 @@ wheelhouse/ /psycopg_c/build/ /psycopg_pool/build/ /tools/build/pg_config_vcpkg_stub/build/ +/tools/isort-psycopg/build/ diff --git a/tools/isort-psycopg/README.rst b/tools/isort-psycopg/README.rst new file mode 100644 index 000000000..fe85fc57c --- /dev/null +++ b/tools/isort-psycopg/README.rst @@ -0,0 +1,27 @@ +Psycopg style isort +=================== + +This is an isort_ plugin to sort: + +- import in length order +- import lists in natural order + +The effect is the same of specifying ``--length-sort`` but only for the module +names. For example:: + + from ccc import aaaa, bbb, cc + from bbbb import ddd, ee + from aaaaa import fff, gg + +Example configuration:: + + [tool.isort] + profile = "black" + length_sort = true + multi_line_output = 9 + sort_order = "psycopg" + +Note: because this is the first day I use isort at all, there is a chance that +this plug-in is totally useless and the same can be done using isort features. + +.. _isort: https://pycqa.github.io/isort/ diff --git a/tools/isort-psycopg/isort_psycopg.py b/tools/isort-psycopg/isort_psycopg.py new file mode 100644 index 000000000..ff5471604 --- /dev/null +++ b/tools/isort-psycopg/isort_psycopg.py @@ -0,0 +1,42 @@ +"""isort function to sort module names by length, objects naturally.""" + +from __future__ import annotations + +import re +import inspect +from typing import Any, Callable, Iterable + +from isort.sorting import naturally + + +def psycosort( + to_sort: Iterable[str], + key: Callable[[str], Any] | None = None, + reverse: bool = False, +) -> list[str]: + # Sniff whether we are sorting an import list (from module import a, b, c) + # or a list of modules. + # Tested with isort 6.0. It might break in the future! + is_from_import = any( + f for f in inspect.stack() if f.function == "_with_from_imports" + ) + + new_key: Callable[[str], Any] | None + if is_from_import: + if key: + old_key = key + + def new_key(s: str) -> Any: + return drop_length(old_key(s)) + + else: + new_key = drop_length + else: + new_key = key + + return naturally(to_sort, key=new_key, reverse=reverse) + + +def drop_length(s: str) -> Any: + """Drop the length prefix from the objects sorted.""" + return re.sub(r"\d+:", "", s) if s else s diff --git a/tools/isort-psycopg/pyproject.toml b/tools/isort-psycopg/pyproject.toml new file mode 100644 index 000000000..c02413977 --- /dev/null +++ b/tools/isort-psycopg/pyproject.toml @@ -0,0 +1,22 @@ +[build-system] +requires = ["setuptools", "wheel"] +build-backend = "setuptools.build_meta" + +[project] +name = "isort-psycopg" +description = "isort plug-in to sort imports by module length first" +# Note: to release a new version: +# python -m build -o dist --wheel . +# twine upload dist/isort_psycopg-*-py3-none-any.whl +version = "0.0.1" + +[project.readme] +file = "README.rst" +content-type = "text/x-rst" + +[[project.authors]] +name = "Daniele Varrazzo" +email = "daniele.varrazzo@gmail.com" + +[project.entry-points."isort.sort_function"] +psycopg = "isort_psycopg:psycosort"