Adam Johnson

Recent Posts

See also posts by tag or search with DuckDuckGo:

Python: fuss-free use of Homebrew libraries for package dependencies

Some Python packages require native libraries to be installed on your system when you install them. For example, mysqlclient requires libssl and libcrypto. If those libraries are missing at install time, clang, the C compiler, fails with a message like:

Read more...

Django: render JavaScript import maps in templates

JavaScript’s import statement lets module scripts import objects from other scripts. For example, you can define a script as a module in HTML:

Read more...

Firefox: disable an extension that’s spamming devtools logs

Browser extensions can run JavaScript within the content of your tabs. This means they can trigger messages that appear in the devtools console. For example, one extension I use logs this warning on every tab:

Read more...

Django: silence “Exception ignored in ... OutputWrapper”

You might see this message when running pytest on your Django project:

Read more...

Python: test for unraisable exceptions with unittest.mock

A few days ago, I blogged about debugging unraisable exceptions with Rich. Here’s a sequel on testing that some block of code doesn’t trigger any unraisable exceptions.

Read more...

Git: force colourization with color.ui or --color

By default, Git only colourizes in its output when writing to an interactive terminal. Sometimes, this heuristic isn’t accurate, for example, when you’re piping Git output through another command. In such cases, you can force colourization on or off with either the color.ui configuration option or the --color option. Let’s look at both in turn.

Read more...

Python: debug unraisable exceptions with Rich

Take this Python class:

Read more...

Git: undo a pull

Okay, so you just ran git pull on a branch, and something broke, so you want to undo it. Here are two ways how.

Read more...

Python: spy for changes with sys.monitoring

Python 3.12 introduced sys.monitoring, a new framework for “monitoring” tools like debuggers and profilers to hook into. It provides fine-grained control so tools can listen only to certain events on specific lines of code. The framework came from PEP 669, thanks to Mark Shannon of the Faster CPython team.

Read more...

Python: create temporary files and directories in unittest

Sometimes, tests need temporary files or directories. You can do this in Python’s unittest with the standard library tempfile module. Let’s look at some recipes to do so within individual tests and setUp().

Read more...

Django: Fail in templates with {% url '' %}

Previously, I covered using 1/0 to crash Python within minimal typing, useful to quickly answer questions like “does the code even get here?”. Recently, I wanted to do the same in Django templates, to trace if a given template was even being rendered, and under which code paths.

Read more...

Django Quiz 2024

Yesterday, I held another quiz at the December edition of Django London. The quiz is a regular tradition at our meetup, a way of having a more relaxed event in December and giving away some nice prizes. This was the sixth quiz that I’ve presented, and the seventh overall.

Read more...

Django: launch pdb when a given SQL query runs

Here’s another technique for using pdb within Django. I will add this to the new debugging chapter of Boost Your Django DX in a future update.

Read more...

Django: launch pdb in templates with a custom {% breakpoint %} tag

In my recent Boost Your Django DX update, I added a new chapter on debuggers. Here’s an extra technique I didn’t finish in time for the update, but I will include it in the next one.

Read more...

Django: fix a view using pdb with breakpoint()

Python’s breakpoint() function opens its debugger, pdb, which pauses the program and allows you to inspect and modify things. Let’s look at an example of using it within a Django view, from a sample project included in Boost Your Django DX.

Read more...

Django: find ghost tables without associated models

Heavy refactoring of models can leave a Django project with “ghost tables”, which were created for a model that was removed without any trace in the migration history. Thankfully, by using some Django internals, you can find such tables.

Read more...

Git: count commits with rev-list

git rev-list lists details about commits (also known as “revisions”, hence the name). Its --count option outputs the count of commits in the given range. Pass it @, the short alias for HEAD, to count commits on the current branch:

Read more...

Django-related Deals for Black Friday 2024

Here are some Django-related deals for this year’s Black Friday (29th November) and Cyber Monday (1st December), including my own.

Read more...

Boost Your Django DX updated again

I have just released the second update to Boost Your Django DX, my book of developer experience (DX) recommendations for Django projects. This update contains a new chapter, changes some recommended tools, and upgrades to Python 3.13 and Django 5.1. Overall, the book is 45 pages longer, now totalling 326!

Read more...

Django: Introducing Djade, a template formatter

Happy DjangoCon US 2024 to you. Whilst I am not there, I have adopted the spirit of the season and got to work hacking together a new tool.

Read more...

Git: find when a commit was reverted or reapplied

Git doesn’t store reversion links between commits. It only relies on commit messages to track this information. When you run git revert, the default message includes a line about the reverted commit:

Read more...

Python: my new uv setup for development

uv is a new, fast Python packaging tool. (I believe it is pronounced as written, “uhv”, rather than spelt out like “you-vee”. This saves a syllable, fitting the tool’s ethos of speed.)

Read more...

Django: speed up tests slightly by disabling update_last_login

Django’s test client provides two methods to log in a user: login() and force_login(). The latter one is faster because it bypasses the authentication backend, including password hashing, and just sets a session to have the user logged in. Typically, you’d want to use it in setUp() like this:

Read more...

Django: hoist repeated decorator definitions

Django provides us with a rich set of view decorators. In this post, we’ll look at a technique for hoisting repeated use of these decorators to reduce repetition.

Read more...

Django: a pattern for settings-configured API clients

Here’s an example of a common pattern in Django projects:

Read more...