Skip to content

Commit 3b5b456

Browse files
authored
Merge pull request #72 from it176131/isort-post
Isort post
2 parents fbd3a8e + 6c65a5d commit 3b5b456

File tree

1 file changed

+144
-0
lines changed

1 file changed

+144
-0
lines changed

_posts/2024-12-12-isort.md

Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
---
2+
layout: "post"
3+
title: "isort + git: Cleaner Import Statements for Those Who Don't Like pre-commit"
4+
date: 2024-12-12
5+
---
6+
7+
> [!NOTE]
8+
>
9+
> This is for the readers who don't want to run [`isort` as a `pre-commit` hook](https://pycqa.github.io/isort/docs/configuration/pre-commit.html),
10+
> but do want to organize their imports in one fell swoop.
11+
>
12+
> Personally, I use [`pre-commit`](https://pre-commit.com/) as it saves me from having to remember to sort my imports before submitting a PR.
13+
> But that's me.
14+
15+
While reviewing pull requests (PRs) at work, I sometimes notice that the imports are kind of... disorganized.
16+
```python
17+
# A made-up example.
18+
19+
from itertools import chain
20+
from . import local_module
21+
import pandas as pd
22+
import numpy as np
23+
from typing import Generator
24+
25+
...
26+
27+
```
28+
I can't fault any single author for this, it just happens over time.
29+
To help myself and future authors of the codebase,
30+
I try to make suggestions that make it easier to read or add a bit more structure.
31+
32+
On a recent PR I made the suggestion to use [`isort`](https://pycqa.github.io/isort/) on all the modified files.
33+
Then it occurred to me that if there were more than a few modified files, this could be quite tedious!
34+
To do this more lazily—er,
35+
I mean _efficiently_!—I could take advantage of [`git`](https://git-scm.com/) to get a list of modified files
36+
and feed them to `isort` as arguments.
37+
38+
# `git` the modified files
39+
> [!NOTE]
40+
>
41+
> If you don't already use `git` to track your files, I highly recommend starting.
42+
> It's helped me in more ways that I can mention, and I find myself learning something new more often than not.
43+
44+
`git` tracks changes to files and writes those as [`commit`](https://git-scm.com/docs/git-commit)s to a [`log`](https://git-scm.com/docs/git-log).
45+
Normally it's a best practice to make changes to a branch different from your primary branch
46+
(i.e. "main", "master", etc.),
47+
then open a pull request to merge those changes into the primary branch.
48+
This keeps code from being pushed to users without being reviewed or passing tests, among other things.
49+
50+
Another benefit of tracking work on a separate branch is
51+
you can see which files have been added or modified when compared with the primary branch with [`git diff`](https://git-scm.com/docs/git-diff).
52+
53+
Assuming we're on our feature branch and synced with the main branch,
54+
we can get the list of files like so:
55+
```shell
56+
$ git diff main --name-only
57+
_posts/2024-12-12-isort.md
58+
```
59+
Here we can see that the only file different from my main branch is "_posts/2024-12-12-isort.md",
60+
the blog post I'm currently writing.
61+
62+
>[!NOTE]
63+
>
64+
> We can go a bit further by limiting the file types like so:
65+
> ```shell
66+
> $ git diff main --name-only -- *.py
67+
> ```
68+
>
69+
> This returns nothing on my machine because I haven't added/modified any git-tracked *.py files on this branch.
70+
71+
# `isort` the modified files
72+
Now that we have a convenient way to identify our modified files,
73+
let's save them to a variable and `isort` them.
74+
75+
First we save:
76+
```shell
77+
$ files=$(git diff main --name-only -- *.py)
78+
```
79+
80+
Then we `isort`:
81+
```shell
82+
$ isort $files
83+
```
84+
85+
And that's it!
86+
Well, technically you would `git commit` your changes and `git push` them to update your PR,
87+
but you get the [`gist`](https://docs.github.com/en/get-started/writing-on-github/editing-and-sharing-content-with-gists/creating-gists). 😉
88+
89+
# Bonus
90+
As a final sendoff,
91+
I'll share the diff-result of applying `isort` to the example import statements above,
92+
as well as my preferred `isort` configurations à la [`.isort.cfg`](https://pycqa.github.io/isort/docs/configuration/config_files.html#isortcfg-preferred-format).
93+
94+
Results:
95+
```shell
96+
$ isort main.py --diff
97+
```
98+
```diff
99+
# A made-up example.
100+
101+
from itertools import chain
102+
+
103+
+import numpy as np
104+
+import pandas as pd
105+
+
106+
from . import local_module
107+
-import pandas as pd
108+
-import numpy as np
109+
110+
...
111+
112+
```
113+
114+
Config:
115+
```text
116+
[settings]
117+
profile = black
118+
line_length = 79
119+
force_alphabetical_sort_within_sections = true
120+
force_sort_within_sections = true
121+
group_by_package = true
122+
honor_noqa = true
123+
remove_redundant_aliases = true
124+
float_to_top = true
125+
color_output = true
126+
combine_as_imports = true
127+
```
128+
129+
<script src="https://giscus.app/client.js"
130+
data-repo="it176131/it176131.github.io"
131+
data-repo-id="R_kgDOK1ukqg"
132+
data-category="Announcements"
133+
data-category-id="DIC_kwDOK1ukqs4CcOnS"
134+
data-mapping="pathname"
135+
data-strict="0"
136+
data-reactions-enabled="1"
137+
data-emit-metadata="0"
138+
data-input-position="top"
139+
data-theme="light"
140+
data-lang="en"
141+
data-loading="lazy"
142+
crossorigin="anonymous"
143+
async>
144+
</script>

0 commit comments

Comments
 (0)