Summary
Astral releases more stuff and takes on more stewardship. Who is surprised?
PEP 768: the plan that will get us to safe debugging for live Python programs.
The Django community keeps the framework relevant.
Mypy is catching up with 3.13 typing features.
Astral doesn't slow down
There is productive, and there is Astral. Clearly unsatisfied with only releasing ruff
+ uv
and taking stewardship of rye
, they decided to also take stewardship of python-build-standalone and released a bunch of features during the holidays.
So while you are wondering what they are juicing with, in the hope you could buy some, here is the rundown:
python-build-standlone (formerly known as the indygreg builds) is a key dependency of rye
and uv
: pre-compiled python distributions that work out of the box on Windows, Mac, and a large spectrum of Linux distros, on a wide range of CPU architectures (in fact the released artifacts are pushing GitHub’s boundaries). They are the secret sauce that lets you install Python with those tools without having to use an installer or a repository, and still provide a unified Python experience. Given the fact that a huge chunk of Python's reported packaging problems are actually bootstrapping problems, this is a major asset in the revolution uv
's team is brewing.
According to the former maintainer, Gregory Szorc, this is the natural conclusion of their collaboration:
PBS today is effectively an Astral maintained project and has been that way for months. As far as I can tell there have been only positive side effects of this transition. When I ask myself why I should continue being the GitHub maintainer, every answer distills down to personal pride or building a personal brand. I need neither.
I agree with Charlie that formally transferring stewardship of my standalone Python builds project to Astral is in the best interest of not only the project itself but of the wider Python community.
Because yes, Astral is not just monstrously efficient with their projects, they also contribute upstream (and they are active on discuss.python.org as well, if you can believe it).
Since we are talking about how much they get done, they also slipped in a few new goodies in uv
, so don't forget to uv self update
(I blinked and it went from 0.5.9 to 0.5.13):
uv run --gui-script
so you can run.pyw
files (.py
files that will not makecmd.exe
appear on Windows).Lock files for that sweet, sweet,
--script
option. A nice addition for when you want to put in prod this one fileflask
orfastapi
little experiment. Or Django now. You'll see :)An
UV_OFFLINE
env var that is the equivalent to add--offline
to all commands that support it. Useful in CI when you don't want to hit the network.uv
will still have full access to the cache though, so if you have a warm run, it will work. And it speeds up everything of course.
Please note that if I sound like a basic fanboy, it's because, at this stage, I am.
PEP 768 – Safe external debugger interface for CPython
Technically created on the 25th of last month, but who is counting?
Right now if you want a debugger to trigger breakpoints with Python, the officially supported way is to either use breakpoint()/pdb.set_trace()
or run your code from a debugger. However, it is very convenient to be able to debug a process that is already running, such as a live production Web server or a long data crunching job so several projects hack their way into providing that the best they can.
PEP 768 is a proposal from our debugging champion Pablo Galindo Salgado teaming up with Matt Wozniski and Ivona Stojanovic to create an official interface in CPython to be used for that purpose.
This will make the process safe, reliable, and faster, not to mention it will abstract the platform-specific details that plague the current solutions.
It will likely land in 3.14 given the discussion thread is mostly focusing on how, and not on why. Which makes sense as the change already landed on Pypy, a project that consistently served as a sandbox to test modern features that regularly find their way into the mainstream Python.
The Django community keeps up the good work
I'm amazed that a project so old keeps seing such activity, especially in the Web space, but not only the framework got itself a brand new steering council, it's always looking to modernize itself.
In our case, it's on the move to replace the old django-admin
+ manage.py
combo for a flask
-like django
general command. No more weird django-admin startproject
you use only once and never again that you have to explain, no more dangling manage.py
file in the project, no more python manage.py
in the tutorial because of Windows users and finally a no more dash in the name so python -m django
will work out of the box.
On top of that, the project would start with a pyproject.toml
file, and it would point to settings.py
, removing the need to fiddle with DJANGO_SETTINGS_MODULE
.
The debate is quite lively, some don't want such deprecation, so drop by and make your voice heard if you want this to happen.
Talking about getting more modern, and nicely in sync with uv
scripts allowing lock files, I just discovered the nanodjango project, a lib to let you fit a Django project in one file, like flask
or fastapi
.
You could already kinda hack it with:
from django.conf import settings
from django.core.management import execute_from_command_line
from django.http import HttpResponse
from django.urls import path
settings.configure(
DEBUG=True,
SECRET_KEY="a-secret-key",
ROOT_URLCONF=__name__,
ALLOWED_HOSTS=["*"],
MIDDLEWARE=[],
INSTALLED_APPS=[
"django.contrib.contenttypes",
"django.contrib.staticfiles",
],
TEMPLATES=[
{
"BACKEND": "django.template.backends.django.DjangoTemplates",
"DIRS": [],
}
],
STATIC_URL="/static/",
)
def index(request):
return HttpResponse("Hello, World!")
urlpatterns = [
path("", index),
]
if __name__ == "__main__":
execute_from_command_line()
But it will quickly get awkward as you use more advanced features.
nanodjango
on the other side, make that a breeze:
from nanodjango import Django
app = Django(DEBUG=True, SECRET_KEY="a-secret-key")
@app.route("/")
def index(request):
return "Hello, World!"
Shorter, natural routing, easy to remember, this a much better XP. But on top of that, you can seamlessly add an ORM model there without having to fight app_name
or trick migrations into working. Even better, it comes with whitenoise (for serving static files in prod) and django-ninja (for FastAPI-like JSON Web API) installed and integrated out of the box.
More importantly, it provides a command to convert your one file humble beginnings into a full-featured Django project if you ever need to.
I've seen other attempts to tackle it, but so far, this is my favorite implementation. And it pairs wonderfully with the new inline dependencies Python syntax.
Mypy is catching up
Latest 1.14 release now supports the full Python 3.13 new typing goodness, including @deprecated
and the new style type variable defaults. You know, the class Stuff[T = int]
to say T
is an int
by default in generics.
No? Don't worry, I forgot about it as well.
Don't get me wrong, it's super nice and will up the ergonomics of generics for all lib writers, but it is indeed reaching into obscure feature territory.
Remember not to install mypy
with uv tools
though, it has the same problems as pipx
for all code-specific tooling. All those should be installed in each project venv as they are tied to the version of Python you are using. With the cache and the hardlink strategy uv
is using, it's fast and doesn't take more space on disk anyway.
Great read, thanks, as always.