This line is in Flask's app.py:
self_ref = weakref.ref(self)
Looks over-engineered. Why not just self?
git blame says 2023
$ git blame -w -M -C -C -C -L355,355 src/flask/app.py
0ec7f713 (pgjones 2023-06-11) self_ref = weakref.ref(self)
"Split the App and Blueprint into Sansio and IO parts." That commit only moved code. Blame tells you who last touched a line, not why it exists.
The real reason is from 2020
$ git log -S"weakref.ref(self)" --oneline
0ec7f713 Split the App and Blueprint into Sansio and IO parts
8efea0cc Break reference cycle created by default in Flask instances.
The weakref stops a memory leak (#3761). "Simplify" it and the leak is back. You'd only find this if you already suspected a story.
So I built Blot
Blot is a pre-commit hook that has read your git history. It warns when a commit:
- removes a fix: edits a line a bug fix added
- re-adds a bug: brings back a line a fix removed
-
forgets a related file: changes
Abut notB, when they always change together
Or ask about any line. It skips commits that only moved code:
$ blot why src/flask/app.py:355
explained by 8efea0cc 2020-10-03 Break reference cycle ... [bug fix]
traced past 0ec7f713 2023-06-11 Split the App and Blueprint ... [refactor]
Local, no AI, no account. Warns, never blocks.
Staying quiet was the hard part
My first version gave Django 26 warnings per 10 commits. So I replayed the last 500 commits of 5 repos, read every warning, and turned each noise pattern into a rule.
| Repo | Before | After |
|---|---|---|
| Flask | 1.96 | 0.10 |
| Express | 1.00 | 0.18 |
| Django | 26.30 | 1.29 |
The replays also found real moments, like Express reverting the CVE-2024-51999 security patch. Blot flagged it.
Try it
pip install blot-git
blot index
blot install-hook
Sym-jay
/
Blot
A pre-commit check that has read your project's history. Sora the slime warns when a change removes a fix, re-adds a fixed bug, or forgets a file that always changes too.
Blot
A pre-commit check that has read your project's history.
Meet Sora, the slime who remembers every fix.
Don't take down a fence until you know why it was put up.
Blot warns you before you commit when your change:
- removes a fix: deletes or edits code that was added to fix a bug
- re-adds a bug: brings back a line that a bug fix deliberately removed
-
forgets a related file: changes
Abut notB, when the two almost always change together
It runs locally, needs no account or AI, and stays quiet unless the history gives it a real reason to speak.
A real run on Flask. Plain git blame points to a 2023 commit that only moved this line; Blot traces past it to the 2020 fix that explains it. (Regenerate with python assets/demo/make_demo.py.)
Status: pre-alpha. Milestones M1 and M2 areβ¦
Pre-alpha. If it cries wolf on your repo, open an issue; that's exactly the feedback I need.
Built with help from Claude (of course, phew); every number here is from a real run.


Top comments (0)