Django’s transaction.on_commit() allows you to run a function after the current database transaction is committed. This is useful to ensure that actions with external services, like sending emails, don’t run until the relevant data is definitely saved.
I joined host Tobias Macey on Podcast.__init__, in Episode 349, published this monday. The episode is titled “Improve Your Productivity By Investing In Developer Experience Design For Your Projects”. We covered various topics related to “developer experience” and general ways to improve it on any Python project.
Here’s a small problem I’ve seen where several modules share versions of the same “constant” variable. It came up in the context of a Django project with multiple settings files, but it could happen in different contexts.
The typing module continues to evolve, with new features in every Python version. This can make it tricky if you’re trying to type code that supports multiple Python versions. To help write such code, Mypy identifies version checks using sys.version_info and reads the appropriate branch.
Python 3.6 reached its end of life on the 23rd December. As its release manager put on the Python forum, it has gracefully “ridden off into the sunset”.
This post is not about importing typing.Optional, but instead imports that are themselves optional. Libraries often have optional dependencies, and the code should work whether or not the import is there. A common pattern to solve this to catch ImportError and replace the module with None:
If you use Gunicorn, it’s likely you have a configuration file. This is a Python module that contains settings as module-level variables. Here’s an example with some essential settings:
Developer Experience (DX) is a catch-all term for anything that can improve your development workflow. Such improvements can help you write better code, faster, with fewer bugs.
The descriptor protocol allow us to completely customize attribute access. Python’s documentation describes the protocol with types involved described with words. Let’s look at how we can write those as type hints.
When dealing with evolvng APIs, it may be useful to rename an attribute in a class, but keep the old name around for backwards compatibility. This would mean making one attribute an alias for another. In this post we’ll look at two ways to achieve this.
I remain convinced that Python’s functools.partial() is underappreciated. Following my previous post, here are three more ways to use partial() with Django.
Python is great for writing scripts for the command line. In this post we’ll look at my script template, an example script, and some alternative versions (without type hints, and in async flavour).
If you’re embarrassed at debugging with print(), please don’t be - it’s perfectly fine! Many bugs are easily tackled with just a few checks in the right places. As much as I love using a debugger, I often reach for a print() statement first.
I recently converted this blog to Pelican, a Python powered static site generator. On the way I added a few customizations. One customization is a Jinja template filter to truncate a post’s HTML as a summary, using Python’s HTMLParser class. Here’s how I wrote it.
Sometimes pip install will flag a warning saying “The candidate selected for download or install is a yanked version”. For example, if we install attrs version 21.1.0:
Black is the de facto standard code formatter for Python, and these days I use it on all my projects. blacken-docs is a tool that also allows you to apply Black to code samples in your docs. I recently rolled it out on my projects to great effect.