[!NOTE]

This is for the readers who don’t want to run isort as a pre-commit hook, but do want to organize their imports in one fell swoop.

Personally, I use pre-commit as it saves me from having to remember to sort my imports before submitting a PR. But that’s me.

While reviewing pull requests (PRs) at work, I sometimes notice that the imports are kind of… disorganized.

# A made-up example.

from itertools import chain
from . import local_module
import pandas as pd
import numpy as np
from typing import Generator

...

I can’t fault any single author for this, it just happens over time. To help myself and future authors of the codebase, I try to make suggestions that make it easier to read or add a bit more structure.

On a recent PR I made the suggestion to use isort on all the modified files. Then it occurred to me that if there were more than a few modified files, this could be quite tedious! To do this more lazily—er, I mean efficiently!—I could take advantage of git to get a list of modified files and feed them to isort as arguments.

git the modified files

[!NOTE]

If you don’t already use git to track your files, I highly recommend starting. It’s helped me in more ways that I can mention, and I find myself learning something new more often than not.

git tracks changes to files and writes those as commits to a log. Normally it’s a best practice to make changes to a branch different from your primary branch (i.e. “main”, “master”, etc.), then open a pull request to merge those changes into the primary branch. This keeps code from being pushed to users without being reviewed or passing tests, among other things.

Another benefit of tracking work on a separate branch is you can see which files have been added or modified when compared with the primary branch with git diff.

Assuming we’re on our feature branch and synced with the main branch, we can get the list of files like so:

$ git diff main --name-only
_posts/2024-12-12-isort.md

Here we can see that the only file different from my main branch is “_posts/2024-12-12-isort.md”, the blog post I’m currently writing.

[!NOTE]

We can go a bit further by limiting the file types like so:

$ git diff main --name-only -- *.py

This returns nothing on my machine because I haven’t added/modified any git-tracked *.py files on this branch.

isort the modified files

Now that we have a convenient way to identify our modified files, let’s save them to a variable and isort them.

First we save:

$ files=$(git diff main --name-only -- *.py)

Then we isort:

$ isort $files

And that’s it! Well, technically you would git commit your changes and git push them to update your PR, but you get the gist. 😉

Bonus

As a final sendoff, I’ll share the diff-result of applying isort to the example import statements above, as well as my preferred isort configurations à la .isort.cfg.

Results:

$ isort main.py --diff
 # A made-up example.
 
 from itertools import chain
+
+import numpy as np
+import pandas as pd
+
 from . import local_module
-import pandas as pd
-import numpy as np

 ...

Config:

[settings]
profile = black
line_length = 79
force_alphabetical_sort_within_sections = true
force_sort_within_sections = true
group_by_package = true
honor_noqa = true
remove_redundant_aliases = true
float_to_top = true
color_output = true
combine_as_imports = true