Recent Posts

See also posts by tag or search with DuckDuckGo:

Python: a quick cProfile recipe with pstats

Python comes with two built-in profilers for measuring the performance of your code: cProfile and profile. They have the same API, but cProfile is a C extension, while profile is implemented in Python. You nearly always want to use cProfile, as it’s faster and doesn’t skew measurements as much.

Read more...

Git: list checked-in symlinks

Git supports storing symbolic links (symlinks) in your repository, which are filesystem links that point to another file or directory. These are great for when you want to have the same file at multiple locations in your repository, such as some configuration file that is used for multiple sub-projects. But how can you list all the symlinks in your repository?

Read more...

GitHub Actions: avoid double runs from on: [push, pull_request]

I’ve often seen a GitHub Actions workflow defined with a trigger like:

Read more...

Docker: disable “What’s next” adverts

On a client project today, I noticed that running docker exec -it tacks this advert on the end of the output:

Read more...

pre-commit: install with uv

pre-commit is my favourite Git-integrated “run things on commit” tool. It acts as a kind of package manager, installing tools as necessary from their Git repositories. This makes it fairly easy to set up: all you need to install is pre-commit itself, and it takes things from there.

Read more...

Git: fix a filename case collision

You may encounter this warning when cloning a Git repository:

Read more...

Docker: remove obsolete version keys from Compose files

If you use Docker Compose, you may see this message:

Read more...

Django: model field choices that can change without a database migration

Adam Hill posted a question on Mastodon: he wants a model field that uses choices that doesn’t generate a database migration when the choices change. This post presents my answer. First, we’ll recap Django’s default behaviour with choice fields, a solution with callable choices, and the drawbacks.

Read more...

Python type hints: mixin classes

In Python, a mixin class is a class that is not intended to be used directly, but instead “mixed in” to other classes through multiple inheritance. Mixins are not really a language feature but more of a conventional pattern allowed by Python’s multiple inheritance rules. Unfortunately, adding type hints to mixin classes can be tricky because they implicitly require subclasses to fit a certain shape.

Read more...

GitHub: render GitHub-Flavored Markdown with the API

GitHub-Flavored Markdown (GFM) is GitHub’s variant of Markdown, with extra features like task lists and alert boxes. It’s used in issues, pull requests, comments, and many other places on GitHub.

Read more...

Django: what’s new in 5.2

Django 5.2 was released last Wednesday, another exciting step forward for our favourite web framework. It comes with a composite of new features, contributed to by many, some of which I am happy to have helped with. Below is my pick of highlights from the release notes.

Read more...

Zsh: clear the “You have mail“ message

Do you see this message when you open a new terminal session?

Read more...

Boost Your Git DX now has a free sample

Last week, I released the second update to my book Boost Your Git DX. Today I’m happy to announce that I have released a free sample of the book.

Read more...

Boost Your Git DX second update out now

Today I have released the second update to Boost Your Git DX, my book of developer experience (DX) recommendations for using Git. Since the last update (2024-04-04), it has grown again by 28 pages, for a new total of 391 pages!

Read more...

Shell: benchmark the difference between two Git branches with hyperfine

hyperfine is a neat tool for benchmarking commands. If you provide it multiple commands, its output includes a comparison, saying which is the fastest, and by how much.

Read more...

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...