Sign in

Adam Johnson

@adamj.eu
3.4K followers 266 following 808 posts

🐴 @djangoproject.com blogger and contributor ✍️ Author of three books on Django and Git 🍕 Django London co-organizer 🇬🇧 London / 🇵🇹 Lisbon

PostsRepliesMedia
Adam Johnson @adamj.eu · 9h
✍️ New post on Zsh’s natural sort order feature, handy for getting your pages in the right order! adamj.eu/tech/2026/09... #Zsh
adamj.eu
Zsh: sort globs in natural order with the (n) glob qualifier - Adam Johnson
Globs sort filenames character by character, so numbered files often come out in a surprising order, with 10 before 2. Zsh has a neat fix for this: the n glob qualifier, which applies a “natural” sort...
020
Adam Johnson @adamj.eu · 29/09/2026
For when crem doesn’t work:
A tub of “Sudocrem”, an antiseptic healing cream.

It gets to the root of the problem.
290
Adam Johnson @adamj.eu · 29/09/2026
📣 Join me on Thursday, 8th October, in Lisbon for a small software engineering meetup! Looking forward to meeting more folks out there. adamj.eu/tech/2026/09... #SoftwareEngineering #Python #Django #Lisbon #Lisboa #Portugal
adamj.eu
Python: join my meetup in Lisbon, 8th October - Adam Johnson
I previously announced my Python optimization workshop in Lisbon, on 10th October (which still has a few places). I am now pleased to add a Python/Django meetup on the Thursday before.
041
Adam Johnson @adamj.eu · 28/09/2026
Still a few spots left!
031
Adam Johnson @adamj.eu · 21/09/2026
✍️ New post on finding big files with Zsh’s glob qualifiers adamj.eu/tech/2026/09... #Zsh
adamj.eu
Zsh: find the largest files with the (OL) glob qualifier - Adam Johnson
Got a directory that you want to tidy up bloat from? Whether you’re trying to find bad build artifacts in your work repository or clear out old cat videos from your home directory, Zsh’s (OL) glob qua...
031
Adam Johnson @adamj.eu · 21/09/2026
🔊 What the Future Holds - S.P.Y. Gorgeous orchestral dnb, amazing London timelapses, still hits big 14 years later. www.youtube.com/watch?v=-X07... #DrumAndBass #London
youtube.com
S.P.Y - What The Future Holds (feat. Ian Shaw) - OFFICIAL VIDEO
YouTube video by Hospital Records
120
Adam Johnson @adamj.eu · 20/09/2026
✍️ New post on using macOS’ caffeinate command, which I recently found useful to keep a code migration script running. adamj.eu/tech/2026/09... #macOS
adamj.eu
macOS: use caffeinate to keep your computer on - Adam Johnson
If you’re starting a long job on your Apple Macintosh Computer and wandering off for a coffee, the machine may go to sleep before it finishes due to inactivity. To prevent that from happening, also gi...
110
Reposted by Adam Johnson
Frank Wiles @fwiles.bsky.social · 19/09/2026
Made a fun little utility for myself over the last hour or so. Using Adam Johnson's new django-mcpz created an MCP in my personal cluster to collect "notes" and then an iOS shortcut to launch Claude in voice chat mode so I can add/edit/retrieve notes while on the go
112
Adam Johnson @adamj.eu · 19/09/2026
🔧 I’m excited to host this optimization workshop in Lisbon next month. Come join me to learn about profiling and optimizing Python code, and maybe even contribute to Django itself. adamj.eu/tech/2026/09... #Python #Django
adamj.eu
Python: join my optimization workshop in Lisbon, 10th October - Adam Johnson
I’m running a workshop in Lisbon next month, and you’re invited!
020
Adam Johnson @adamj.eu · 16/09/2026
✍️ New post on serving the change password well-known URL in Django Add this one redirect and two tests (you won't believe #2) to make your site more user-friendly for users with compromised passwords. adamj.eu/tech/2026/09... #Django #Security
adamj.eu
Django: serve the change password well-known URL - Adam Johnson
When a password manager detects that a user’s password has been leaked or reused, it can prompt them to change it, but the password change URL varies by site. The web’s answer to such discovery proble...
083
Adam Johnson @adamj.eu · 16/09/2026
🧪 I just released unittest-parametrize 1.9.0. This package helps you make parametrized tests that work with the grain of unittest, but can still be run with pytest. github.com/adamchainz/u... #Python
github.com
unittest-parametrize/CHANGELOG.rst at main · adamchainz/unittest-parametrize
Parametrize tests within unittest TestCases. Contribute to adamchainz/unittest-parametrize development by creating an account on GitHub.
120
Adam Johnson @adamj.eu · 15/09/2026
🎁 Introducing django-mcpz: easy peasy MCP servers in Django! This new package lets you build an MCP server in your Django project, letting LLMs do things on your site on behalf of your users. adamj.eu/tech/2026/09... #Django #AI
adamj.eu
Django: introducing django-mcpz, for making MCP servers - Adam Johnson
I made another package! Say hello to django-mcpz, for building Model Context Protocol (MCP) servers in your Django project.
280
Reposted by Adam Johnson
Simon Willison @simonwillison.net · 14/09/2026
Built a little local web app to help edit commit messages for a repo simonwillison.net/2026/Sep/14/...
Screenshot of the commit-rewriter web interface. A heading reads commit-rewriter above the repository path and current branch and commit hash, with a short description of the tool. A toolbar shows a pending edits count with Discard drafts and Rewrite commit messages buttons, followed by a search box for message, author, or hash and an Edited only checkbox. A left sidebar titled Navigate commits lists recent commit messages with their short hashes. The main panel shows a card for each commit with its hash, author and timestamp, an editable text area containing the commit message, and a View full formatted diff toggle.
7594
Adam Johnson @adamj.eu · 09/09/2026
⏳ I just released time-machine 3.5.1 with 13 bug fixes. Two were reported by humans. The rest came from prompting Claude Fable with just "Find and fix bugs". time-machine.readthedocs.io/en/latest/ch...
time-machine.readthedocs.io
Changelog - time-machine 3.5.1 documentation
130
Adam Johnson @adamj.eu · 01/09/2026
🎲 Just released pytest-randomly 5.0.0 The headline breaking change fixes combination with other test reordering plugins, including pytest-django. Previously, the same seed could produce different test orders between nearly-identical environments. Oops! #Python #pytest pypi.org/project/pyte...
pypi.org
pytest-randomly
Pytest plugin to randomly order tests and control random.seed.
120
Adam Johnson @adamj.eu · 25/08/2026
✍️ Zsh lets you manipulate filenames with modifiers, which I recently found useful when converting files between formats. adamj.eu/tech/2026/08... #Zsh
adamj.eu
Zsh: manipulate filenames with modifiers like :r (root) and :e (extension) - Adam Johnson
Zsh modifiers are a family of suffixes that transform words as they’re expanded. Several of them are dedicated to slicing up filenames, replacing fiddly calls to dirname, basename, and friends. Let’s ...
020
Adam Johnson @adamj.eu · 20/08/2026
We’re so back #htmx
051
Adam Johnson @adamj.eu · 18/08/2026
✍️ I used my leet prompt engineering skillz to fix a bunch of bugs in django-upgrade adamj.eu/tech/2026/08... #Django #Python #AI
adamj.eu
Django: django-upgrade 1.32.0 out now, with 44 AI-assisted bug fixes - Adam Johnson
django-upgrade is my tool for automatically upgrading your project code for new Django versions. It rewrites your Python files to fix deprecations and adopt some new features, taking a chunk of the mo...
190
Reposted by Adam Johnson
Christopher Trudeau @trudeau.dev · 14/08/2026
On this week's episode, @digiglean.bsky.social and I talk about testing in Django, SIMD, data visualization and more. With content from: @djangoproject.com @adamj.eu @retr0.id @purplesyringa.bsky.social and others not on the 🦋 Also, this time I might even include a link! buff.ly/rTT0o1M
realpython.com
Episode #307: Improving NumPy Performance on Free-Threaded Python – The Real Python Podcast
What bottlenecks were preventing NumPy from scaling on free-threaded Python? Christopher Trudeau is back on the show this week with another batch of PyCoder's Weekly articles and projects.
021
Adam Johnson @adamj.eu · 12/08/2026
📦 New package day! This time a Rusty rewrite of the emoji package: 3.5x faster for conversion, 70 times faster for deconversion, and using about 40% less memory. adamj.eu/tech/2026/08... #Python #Rust
adamj.eu
Python: introducing emojet, a fast emoji lookup library - Adam Johnson
New package just landed!
160
Adam Johnson @adamj.eu · 08/08/2026
✍️ I just released a new version of my little Python profiler, tprof, with less overhead for more accurate results. adamj.eu/tech/2026/08... #Python
adamj.eu
Python: tprof 1.3.0: now with less overhead - Adam Johnson
Back in January, I introduced tprof, a targeting profiler for Python 3.12+ that measures the time spent in specific functions, rather than your whole program. As a reminder, here’s the basic usage, sp...
030
Adam Johnson @adamj.eu · 07/08/2026
🎨 I’m really enjoying the redesigned PyPI project pages. Thanks to Nicole Harris and team for making these improvements! Blog post: blog.pypi.org/posts/2026-0... #Python
Django’s project page on PyPI, showcasing the new design.
070
Adam Johnson @adamj.eu · 07/08/2026
✍️ New package: django-msgspec, providing Django integrations with msgspec’s faster JSON serialization and deserialization. adamj.eu/tech/2026/08... #Django
adamj.eu
Django: introducing django-msgspec - Adam Johnson
It’s another day, another new package day here. Say hello to django-msgspec, a package of drop-in replacements for Django and Django REST Framework (DRF) components backed by msgspec.
150
Adam Johnson @adamj.eu · 07/08/2026
✍️ The story of a 50x optimization I made in Git earlier this year. adamj.eu/tech/2026/08... #Git
adamj.eu
Git: my git stash -p optimization in Git 2.55 - Adam Johnson
I got another commit merged in Git 2.55 (2026-06-29), yay! The release note reads:
030
Adam Johnson @adamj.eu · 07/08/2026
✍️ List the files present in any Git commit without checking it out. adamj.eu/tech/2026/08... #Git
adamj.eu
Git: list files at a given commit with ls-tree - Adam Johnson
To list all files in your repository as they were at a given commit, use git ls-tree with its -r and --name-only options:
010
Adam Johnson @adamj.eu · 06/08/2026
😍 wowza
030
Adam Johnson @adamj.eu · 06/08/2026
📦 Just released django-htmx 1.29.0 which now vendors a bunch of htmx extensions, updates the vendored htmx versions, and adds support for htmx v4's polling extension django-htmx.readthedocs.io/en/latest/ch... #Django #htmx
django-htmx.readthedocs.io
Changelog - django-htmx 1.29.0 documentation
061
Adam Johnson @adamj.eu · 05/08/2026
🆙 Updated my post on unittest base test cases with a new preferred technique: using a plain class as a container. adamj.eu/tech/2025/05... #Python #unittest
adamj.eu
Python: sharing common tests in unittest - Adam Johnson
A neat testing pattern is writing common tests in a base class and then applying them to multiple objects through subclassing. Doing so can help you test smarter and cover more code with less boilerpl...
020
Adam Johnson @adamj.eu · 05/08/2026
✍️ New post covering how to read your local Git log while skipping commits from a certain author. In my case, it was the ol’ Dependabot. adamj.eu/tech/2026/08... #Git #GitHub
adamj.eu
Git: exclude commits by an author in git log with --perl-regexp - Adam Johnson
git log has an --author option to limit the output to commits from matching authors:
010
Adam Johnson @adamj.eu · 05/08/2026
Django 6.1 is out !!! www.djangoproject.com/weblog/2026/... #Django
djangoproject.com
Django 6.1 released
Posted by Jacob Walls on Aug. 5, 2026
042
Adam Johnson @adamj.eu · 04/08/2026
✍️ A neat trick I learned using Zsh to list recently modified files. adamj.eu/tech/2026/08... #Zsh
adamj.eu
Zsh: list recently modified files with (m0) glob qualifiers - Adam Johnson
My downloads directory is a junk pile that I just never get around to fully clearing. So if I’ve just downloaded a bunch of files, I normally want to work with them and ignore the rest of the files.
040
Adam Johnson @adamj.eu · 03/08/2026
✍️ New post demonstrating the runtime advantage of my package time-machine over its inspiration, freezegun. adamj.eu/tech/2026/08... #Python
adamj.eu
Python: how time-machine is O(1) where freezegun is O(n) - Adam Johnson
time-machine is my library for mocking the current date and time in Python tests. Its headline advantage over freezegun, the library that inspired it, is speed.
061
Reposted by Adam Johnson
Hugo van Kemenade @hugovk.dev · 03/08/2026
"Python has decided to enable frame pointers by default and encourage the ecosystem to do so as well, to make debugging easier for us all, so time-machine is joining the party." Enabled by default for 3.15, do this for older versions: github.com/adamchainz/t... #Python
github.com
Build with frame pointers enabled by adamchainz · Pull Request #627 · adamchainz/time-machine
0114
Reposted by Adam Johnson
Jake Howard 🍊 @theorangeone.net · 31/07/2026
I replaced linkchecker with @adamj.eu's django-crawl on my website. Shaved 2 minutes off my CI time, with a fancy UI, fewer bodges, and a sprinkling of #rust for good measure 🙌 github.com/adamchainz/d...
github.com
GitHub - adamchainz/django-crawl: An in-process site crawler using Django’s test client.
An in-process site crawler using Django’s test client. - adamchainz/django-crawl
011
Adam Johnson @adamj.eu · 31/07/2026
✍️ time-machine 3.3.0 is out, with Python 3.15 support, performance improvements, subinterpreter support, and various bug fixes. Check it out, and if you’re using freezegun, try the updated Migration CLI to convert and speed up your tests. adamj.eu/tech/2026/07... #Python
adamj.eu
Python: time-machine 3.3.0 lets your tests time-travel even faster - Adam Johnson
time-machine is my library for mocking the current date and time in Python tests. I’ve just released version 3.3.0 with a decent number of changes, so here’s a lovely summary for you.
0122
Adam Johnson @adamj.eu · 27/07/2026
What do you see?
https://www.mixfont.com/experiments/decoy-font
361
Adam Johnson @adamj.eu · 27/07/2026
big horse energy
030
Adam Johnson @adamj.eu · 27/07/2026
✍️ New post on a Python testing technique: inspecting interleaved calls across multiple mocks with attached mocks. #Python adamj.eu/tech/2026/07...
adamj.eu
Python: inspect unittest.mock calls with attached mocks - Adam Johnson
When you use a unittest.mock mock, you often make assertions on the calls it received, such as through the mock_calls list. But sometimes you want to assert on the order of calls across multiple mocke...
030
Adam Johnson @adamj.eu · 25/07/2026
✍️ New post on using unittest.mock to spy on function calls. 🕵️‍♂️ I recently learned how to use the wraps argument to track calls to a target function for later assertions. Handy for testing things like “is caching working?” without mocking the function completely. #Python adamj.eu/tech/2026/07...
adamj.eu
Python: spy on function calls with unittest.mock’s wraps - Adam Johnson
Testing terminology distinguishes between different kinds of test doubles, including:
040
Adam Johnson @adamj.eu · 24/07/2026
✍️ Django’s released code words, up to the pending Django 6.1 “mélange”. adamj.eu/tech/2026/07... #Python #Django
adamj.eu
Django: release code words up to 6.1 - Adam Johnson
Did you know that each Django release has a “code word” associated with it? It’s hidden in plain sight, in the announcement blog post describing the list of features coming in the next version. I thin...
020
Adam Johnson @adamj.eu · 22/07/2026
✍️ Introducing django-crawl, a tool for crawling your local Django site, useful for quickly finding what’s broken or performing site-wide checks. adamj.eu/tech/2026/07... #Django #Python
adamj.eu
Django: introducing django-crawl - Adam Johnson
I recently migrated one of my client projects from the legacy django-csp package to Django 6.0’s built-in Content Security Policy (CSP) support (release note). This security header is a powerful tool ...
041
Adam Johnson @adamj.eu · 15/07/2026
✍️ New post introducing django-orjson, my new package integrating the fast JSON library orjson with various Django and DRF components. Claim 10x faster serialization and 2x faster deserialization with minimal code changes. adamj.eu/tech/2026/07... #Django
adamj.eu
Django: introducing django-orjson - Adam Johnson
Just as cars painted red are known to be faster, libraries implemented in Rust are also known to be faster. Today’s example is orjson, a Rusty replacement for Python’s built-in json module, boasting 1...
060
Adam Johnson @adamj.eu · 14/07/2026
✍️ New post covering a debugging hack using gc.get_objects() to find all instances of a class in Python. adamj.eu/tech/2026/07... #Python
adamj.eu
Python: find all instances of a class with gc.get_objects() - Adam Johnson
Here’s a lovely hack that I’ve used when machete-mode debugging.
040
Adam Johnson @adamj.eu · 27/06/2026
✍️ New post on using WeakKeyDictionary to store extra per-object data Documenting a pattern I’ve used in several places to store extra data without touching the object itself. adamj.eu/tech/2026/06... #Python
adamj.eu
Python: store extra data for objects in a WeakKeyDictionary - Adam Johnson
In several programs, I’ve wanted to solve the problem of associating extra data with an object. For example, in django-upgrade, the individual “fixer” functions often want to store extra data per visi...
040
Adam Johnson @adamj.eu · 25/06/2026
🚅 django-upgrade 1.31 is out! * Django 6.1 support * 6 new fixers, 5 for Django 6.1 * Extensions to 5 existing fixers * 4 bug fixes Test on your projects today, please 😌 django-upgrade.readthedocs.io/en/latest/ch... #Django
django-upgrade.readthedocs.io
Changelog - django-upgrade 1.31.0 documentation
061
Adam Johnson @adamj.eu · 31/05/2026
✍️ New post about a new package, django-integrity-policy, for setting the new Integrity-Policy security header. adamj.eu/tech/2026/05... #Django #Python
adamj.eu
Django: introducing django-integrity-policy - Adam Johnson
Back in January, Firefox’s Security & Privacy Newsletter for 2025 Q4 piqued my interest with this mention:
062
Reposted by Adam Johnson
Christopher Trudeau @trudeau.dev · 08/05/2026
On this week's episode, @digiglean.bsky.social and I talk about decoupling business logic from the Django ORM, web scraping, and more. With content from: @adamj.eu @carltongibson.bsky.social @alsweigart.bsky.social and others not on the 🦋 Plus: CB shows his chops! 🎸
buff.ly
Episode #294: Declarative Charts in Python & Discerning Iterators vs Iterables – The Real Python Podcast
What if you could build charts in Python by describing what your data means, instead of scripting every visual detail? Christopher Trudeau is back on the show this week with another batch of…
051
Adam Johnson @adamj.eu · 20/04/2026
✍️ New post detailing a workaround I came up with for “leak” beahviour from Python 3.14’s new garbage collection algorithm. Topical as @hugovk.dev recently announced that the algorithm will be reverted in the next patch release! adamj.eu/tech/2026/04... #Django #Python
adamj.eu
Django: fixing a memory “leak” from Python 3.14’s incremental garbage collection - Adam Johnson
Back in February, I encountered an out-of-memory error while migrating a client project to Python 3.14. The issue occurred when running Django’s database migration command (migrate) on a limited-resou...
3102
Adam Johnson @adamj.eu · 03/04/2026
✍️ New post introducing profiling-explorer, a tool for exploring Python profiling data (pstats files). Use it with the classic cProfile (now called profiling.tracing) or Python 3.15’s new sampling profiler, Tachyon (profiling.sampling). adamj.eu/tech/2026/04... #Python
adamj.eu
Python: introducing profiling-explorer - Adam Johnson
I’ve made another package! Like icu4py, which I made in February, it was sponsored by my client Rippling. And like tprof, which I made in January, it’s a profiling tool!
050
Adam Johnson @adamj.eu · 31/03/2026
Nice IPython Easter Egg! 🏳️‍⚧️ #TransDayOfVisibility #Python
Running IPython today gives you the tip "Happy International Transgender Day of Visibility! You are valid. You matter."
050