By default, Zsh globs skip hidden files and directories, meaning those with names starting with a dot. For example, in a project directory, * misses all the configuration files and directories:
Sometimes you want your shell scripts to take options, like --verbose or --help, along with any positional arguments. Handling options is fiddly to do by hand, with the traditional portable approach being a large block of code using a while loop, a case statement, and some shifts. Bash has the getopts builtin, but it only handles single-letter options, like -v. Zsh also has getopts, for compatibility, with the same limitation.
Django projects end up slotting into a bunch of software release cycles: Django itself, Python, database servers, cache servers, and more. It can be hard for us developers to keep track of all of them, with their different support policies and end-of-life dates, and running an unsupported version means missing out on important security or bug fixes.
When contributing to Django, you’ll want to run its test suite to check your changes. The official contributing docs cover setup in Running the unit tests, using a virtual environment and pip. Here’s an alternative guide using uv.
If your site has companion Apple or Android apps, you probably want links to your site to open in those apps, when installed. Both platforms support this, with Apple calling the feature Universal Links and Android calling it App Links.
When a security researcher finds a vulnerability in your site, they need a way to tell you about it. Without a clear contact, they may resort to guessing at addresses like security@<yourdomain>, messaging random folks on social media, or give up. And of course, in the worst case, they might just publish the details, leaving you to find out when attackers do.
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 nglob qualifier, which applies a “natural” sort, treating any run of digits as a number rather than a string of characters.
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.
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 qualifier can help you find the largest files.
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 give your computer a boost with the caffeinate command, a macOS built-in since 2012 (OS X Mountain Lion).
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 problems is the reserved /.well-known/ URL namespace (RFC 8615), home to machine-readable files and endpoints like security.txt. A Well-Known URL for Changing Passwords is the web specification that uses this namespace to fix password page discovery. It reserves the URL path /.well-known/change-password to redirect to your actual change password page, wherever that lives.
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 take a look at them now!
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 monotony out of upgrading between Django versions.
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: