Enforcing Python imports' order with isort, Makefiles, and Vim ============================================================== .. post:: 2021-12-27 :author: Michal Bultrowicz :tags: Python, Linux, CLI, Vim I finally integrated `isort `_ into my toolbox. I think that the job of changing code files belongs to the editor (or an IDE), so I made Vim run ``isort`` automatically, while the import order enforcement in a project is done via Makefile (which can be run the same way by developers and the CI/CD pipeline). This post may be a bit chaotic, but it should give a glimpse of how I like to set up automation around quality assurance (like tests, linting, static checks, etc.) in my projects. I'd like to produce more comprehensive write-ups at some point in the future. isort installation ------------------ First, the ``isort`` Python package needs to be available for your editor and the ``make`` commands wherever you are working, so: - add ``isort`` to your project's dependencies and virtualenv. I use `poetry `_ for that: ``poetry add --dev isort`` - make ``isort`` available outside of any virtualenv (e.g. for small scripts), by installing it for your user. I use `pipx `_ for that: ``pipx install isort`` VIM (editor) setup ------------------ If you're not using Vim you'll probably still find an ``isort`` plugin for your editor. Or maybe your IDE has import ordering built-in, like `Pycharm `_. You'll need a Vim plugin - `ALE `_ - to run ``isort``. I recommend `vim-plug `_ as the plugin manager. You can see how I set it up at the top of my `.vimrc `_. You can add the plugin by adding ``Plug 'dense-analysis/ale'`` in the right place in your ``.vimrc``, and then issuing the ``:PlugUpdate`` command to Vim. Then, add some more config into ``.vimrc``:: " make ALE use isort let g:ale_fixers = { 'python': ['isort'] } " this will make :ALEFix, and thus import fix to run on file save let g:ale_fix_on_save = 1 Configuring isort ----------------- Know that you can `configure some aspects `_ of how ``isort`` works. For example, I like to sort all my imports alphabetically on the referenced packages, without separating ``import XXX`` and ``from XXX import YYY`` statements. So I put this in my `pyproject.toml `_:: [tool.isort] force_sort_within_sections = true Use in project's Makefile ------------------------- I like to have a ``validate`` Makefile target that runs all tests and static code checks. That target should be run by developers and the CI/CD pipeline. ``isort`` can work as one of the static checks, if used with ``-c`` flag. So we can have a Makefile looking like this:: validate: static_checks test test: pytest -v tests/ static_checks: isort -c the_code pylint the_code Bonus: automatic imports fixer for Vim -------------------------------------- One of the features I'm missing from Pycharm is automatic adding of missing imports. There's a plugin called `vim-nayvy `_ that can do that, but I wasn't able to get it to work with anything other than standard library imports. That is, it wouldn't fix imports of third-party packages from ``site-packages`` or project/local packages. Maybe that has something to do with me not having a Python `Language Server `_ running with NeoVim... I'll see about that some other time.