Recent Posts

See also posts by tag or search with DuckDuckGo:

Python: use re.prefixmatch() instead of re.match() from Python 3.15

Take this validation function:

Read more...

Python: fix SyntaxWarning: invalid octal escape sequence

Take this code:

Read more...

Python: fix TypeError: NamedTuple() got an unexpected keyword argument

Take this code, defining a small NamedTuple with a keyword argument per field:

Read more...

Python: introducing emojet, a fast emoji lookup library

New package just landed!

Read more...

Python: tprof 1.3.0: now with less overhead

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, specifying a target function with -t and a script to run:

Read more...

Django: introducing django-msgspec

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.

Read more...

Git: my git stash -p optimization in Git 2.55

I got another commit merged in Git 2.55 (2026-06-29), yay! The release note reads:

Read more...

Git: list files at a given commit with ls-tree

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:

Read more...

Zsh: select files with arbitrary code in (e) or + glob qualifiers

Zsh glob qualifiers can select files by many built-in attributes: type, size, modification time, and more. But when no built-in qualifier fits, you can bring in the e or + qualifiers to run arbitrary code, making globs a fully programmable file filter. With great power comes great responsibility!

Read more...

Git: exclude commits by an author in git log with --perl-regexp

git log has an --author option to limit the output to commits from matching authors:

Read more...

Zsh: list recently modified files with (m0) glob qualifiers

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.

Read more...

Python: how time-machine is O(1) where freezegun is O(n)

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.

Read more...

Python: time-machine 3.3.0 lets your tests time-travel even faster

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.

Read more...

Python: fix ValueError: day of month directive '%d' may not be used without a year directive

Take this code, parsing the date of an annually recurring event that only has a month and day, such as a work anniversary:

Read more...

Python: fix TypeError: NotImplemented should not be used in a boolean context

Take this class, which implements __eq__() and derives __ne__() from it:

Read more...

Python: inspect interleaved unittest.mock calls with attached mocks

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 mocked functions, for example to check that steps in a process happen in the right sequence.

Read more...

Python: spy on function calls with unittest.mock’s wraps

Testing terminology distinguishes between different kinds of test doubles, including:

Read more...

Django: release code words up to 6.1

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 think this is a lovely little tradition.

Read more...

Django: introducing django-crawl

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 for preventing unwanted content from being loaded on your site, so configuration correctness is paramount. The migration was fairly straightforward, but a few pages had complicated overrides, so I wanted to be sure that no CSP headers had been changed by my swapping of CSP implementations.

Read more...

Django: introducing django-orjson

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 10x faster serialization and 2x faster deserialization.

Read more...

Python: find all instances of a class with gc.get_objects()

Here’s a lovely hack that I’ve used when machete-mode debugging.

Read more...

Python: store extra data for objects in a WeakKeyDictionary

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 visited ast.Module object.

Read more...

Django: introducing django-integrity-policy

Back in January, Firefox’s Security & Privacy Newsletter for 2025 Q4 piqued my interest with this mention:

Read more...

Django: fixing a memory “leak” from Python 3.14’s incremental garbage collection

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-resource server, and seemed to be caused by the new incremental garbage collection algorithm in Python 3.14.

Read more...

Python: introducing profiling-explorer

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!

Read more...