Planet Python
Last update: August 29, 2026 09:48 PM UTC
August 28, 2026
Django Weblog
Django Developers Survey 2026 results
The results from the 2026 Django Developers Survey are now available. This is the fifth annual report conducted from May to July 2026 by the Django Software Foundation in collaboration with JetBrains PyCharm.
The full report includes infographics, quotes, and dedicated sections so you can easily navigate the results. There is also a The State of Django 2026: Boring is so back blog post highlighting key Django trends in 2026 and actionable ideas for your own Django development.
The Django Chat podcast also covers the survey in a special summer episode, from Django 6.1 and HTMX to async, AI, deployment, testing, and Python tooling.
PyCharm
The State of Django 2026: Boring is so back
Welcome to the highlights from the fifth annual Django Developers Survey, a collaboration between the Django Software Foundation and PyCharm. This year’s report draws on responses from nearly 3,500 Django developers across more than 40 countries — from students in their first year to veterans with decades of experience. In software, “boring” is a compliment. […]
Security Incident Affecting JetBrains Cadence
We are investigating a security incident affecting JetBrains Cadence. Cadence is a JetBrains-hosted service that integrates with PyCharm through an optional plugin, and lets you run your projects on cloud compute resources. Our investigation has confirmed unauthorized access to the service and the exposure of customer data associated with its use. We have contacted affected […]
Python Software Foundation
Georgi Ker: 2026 PSF Board Election Candidate Interview
August 27, 2026
Python Morsels
When to use NotImplemented
When should you return NotImplemented from a dunder method? Why not return False or raise an exception instead?
Dunder methods return NotImplemented
Integers and floating point numbers can be compared with equality:
>>> a = 3
>>> b = 3.0
>>> a == b
True
This is powered by the __eq__ method.
But strangely, if we call the __eq__ method on an integer, giving it a floating point number, we'll get back NotImplemented:
>>> a = 3
>>> b = 3.0
>>> a.__eq__(b)
NotImplemented
But if we do the same thing on a floating point number, giving it an integer, we get the answer we're expecting:
>>> a = 3
>>> b = 3.0
>>> b.__eq__(a)
True
The same thing happens with many other operations in Python.
For example, the + operator is powered by the __add__ method:
>>> a = 3
>>> b = 3.0
>>> b + a
6.0
But just as with equality, floating point numbers can be added to integers, but integers cannot be added to floating point numbers:
>>> a = 3
>>> b = 3.0
>>> b.__add__(a)
6.0
>>> a.__add__(b)
NotImplemented
What is the NotImplemented value and why do we get it?
NotImplemented means "I don't know"
Dunder methods that perform an …
Read the full article: https://www.pythonmorsels.com/when-to-use-notimplemented/
Robin Wilson
How to fix a weird pandas and pyarrow issue with BirdNetPi
Summary: If you get Python crashing immediately in BirdNetPi, try uninstalling the pyarrow Python package. I’ve got a BirdNetPi set up at home. This is a bit of software that runs on a Raspberry Pi and listens on a microphone (I’ve mounted mine on the outside of an upstairs window, using a 3D printed mount/cover […]
The Python Show
57 - Python Developer Tooling Handbook with Tim Hopper
In this episode of the Python Show Podcast, I am pleased to have Tim Hopper as my guest.
Python Software Foundation
Jeremy Tanner: 2026 PSF Board Election Candidate Interview
PyCharm
OpenTelemetry Comes to IntelliJ IDEA, GoLand, PyCharm, and WebStorm. The OpenTelemetry plugin has broken out of the confines of JetBrains Rider. No sandbox exploit was involved – this escape was planned by our developers. With the 2026.2 release, the OpenTelemetry plugin is now available in IntelliJ IDEA, GoLand, PyCharm and WebStorm. Rider users needn’t worry […]
PyCon Ireland
PyCon Ireland 2026 Updates & Final Call for Proposals
PyCon Ireland 2026 will take place on 21 November in the Dublin city centre. Submit your talk and workshop proposals by 30 August.
Core Dispatch
Core Dispatch #10
Welcome back to Core Dispatch! This edition covers August 5 through August 27, 2026. Python 3.12.14, 3.11.16, and 3.10.21 shipped on August 12. Next up is Python 3.15.0 release candidate 2, due September 1. There are five new PEPs to catch up on. [PEP 805](https://peps.python.org/pep-0805/) propose
August 26, 2026
Talk Python to Me
#560: Building a Research OS: From Django to 30,000 Samples
In 2020, a gastroenterologist in Glasgow did the math on his new research study and came up with 30,000 samples, arriving over two years from three cities and a dozen hospitals. He asked around about how researchers keep track of that. The answer was Microsoft Excel. Shaun Chuah had written some HTML by hand in Notepad back in high school and that was about the whole of his programming experience, so he opened the Django tutorial and started reading. Six years later that app is Foundry120, holding 10 terabytes of clinical and genomics data with an agentic AI running on top of it.
Rodrigo Girão Serrão
Why OOP exists
Learn the fundamental principles behind OOP and how they connect to the syntax of Python.
Introduction
Welcome! This article will teach you the core ideas behind object-oriented programming, commonly known as OOP. This is the article I wish I read many years ago, when I was first learning about OOP in Python.
If you're new to OOP, this article will explain why OOP exists, how it works, and how to work with OOP in Python. If you think you already know OOP, this article will change the way you think about programming and Python.
Code is about real-world things
Let me tell you about a programming project I had to do in college where you had to write a library management service. We were expected to work in pairs and I was paired with my good friend Tito.
Tito and I sat down and started going through the problem statement, figuring out what we needed to implement. We got to a point where Tito turned to me and said:
“It's not obvious to me what's the best way to represent a book in our program. Maybe you can start implementing the search functionality and I'll think about this for a while.”
The search functionality was a set of functions that the problem statement required us to implement:
find_by_title(catalog, search_term): returns a sublist with the books whose title contains the given search termfind_by_genre(catalog, genre): returns a sublist with the books of the given genrefind_by_author(catalog, author): returns a sublist with the books written by the given author
I nodded, but then I thought about it for a second. If I don't know anything about how to work with books, there's no way I can implement these three functions. Tito agreed with me and told me he'd provide me with these functions:
book_title(book): returns the title of the given bookbook_genre(book): returns the genre of the given bookbook_author(book): returns the author of the given book
He told me to think of these functions as auxiliary functions that he would implement. I didn't have them yet, but I could write my search functions trusting he'd implement them correctly.
In OOP, you have entities with associated data (books with authors, titles, and genres) and a set of functions to operate on those entities (the functions find_by_xxx).
Now, think about it for a second.
Can you implement the functions find_by_title, find_by_genre, and find_by_author, using the auxiliary functions that Tito will implement?
How would you go about it?
I worked on it for a bit, and eventually used a list comprehension to define the function find_by_title:
def find_by_title(catalog, search_term):
search_term = search_term.casefold()
return [
book
for book in catalog
if search_term in book_title(book).casefold()
]
The function find_by_title goes through the list of books called catalog with a loop and uses the auxiliary function book_title to retrieve the title.
It then uses casefold to perform a case-insensitive search.
Something worth...
LernerPython blog, from Reuven Lerner
MIT just called for an educational revolution
As someone who teaches Python programming for a living, I’ve spent the last few years wrestling with the educational implications of AI. I’m changing everything I do to adjust to […]
The post MIT just called for an educational revolution appeared first on LernerPython.
PyCharm
OpenTelemetry Comes to IntelliJ IDEA, GoLand, PyCharm, and WebStorm
Python Bytes
#493 CalVer and LTS
Topics include Web UIs for your reverse proxy, , , and Django’s annual releases make every version an LTS.
August 25, 2026
Django Weblog
PyCharm & Django Fall Fundraiser
We are back with our friends at JetBrains for the second of the two "Buy PyCharm, Support Django" fundraisers we run together each year. Our spring campaign was the first. It remains one of the most impactful ways the community can support the Django Software Foundation.
Your support of this campaign helps fund key initiatives such as:
- A Django Executive Director: Funding our first Executive Director, who will lead fundraising, operations, and community coordination for the Foundation.
- Django Fellows: Ensuring the rapid development and maintenance of Django.
- Django Girls: Making the Django community accessible to programming beginners around the world.
- International events and conferences: Supporting DjangoCons, one-day events, meetups, and other community gatherings around the world.
- Djangonaut Space: Onboarding new contributors to the Django project.
The Executive Director role is new, which is why this campaign matters more than usual. The DSF raises around $300,000 a year today. Reaching $500,000 is what makes a full-time Executive Director sustainable, and campaigns like this one are how we close that gap. If leading that work sounds like you, applications are open until September 14, 2026.
How the campaign works
The campaign runs until September 10, 2026. When you buy a new PyCharm license or renew an existing one at a 30% discount through our special campaign link, JetBrains will donate an equal amount to the Django Software Foundation. You get a professional IDE that is trusted by Django developers worldwide, and the DSF receives a matched contribution.
Get 30% off PyCharm, Support Django
Thank you, JetBrains
Beyond this campaign, JetBrains contributes to the Django ecosystem in ways that are easy to overlook but hard to overstate. The 2026 Django Developers Survey was published earlier this summer, and along with the Python Developers Survey, it gives the entire community a clearer picture of where Django and Python are heading each year.
"JetBrains is one of our most generous fundraising partners year after year, helping us sustain and grow the Django ecosystem. We deeply appreciate their commitment, leadership, and collaboration."
Jeff Triplett, President, Django Software Foundation
Thank you to JetBrains for another year of partnership, and thank you to everyone who participates in this campaign. Together, we can ensure the continued success and growth of the framework we all rely on.
Other ways to donate
If you would like to donate in another way, especially if you are already a PyCharm customer, here are other ways to donate to the DSF:
- On our website via credit card
- Via GitHub Sponsors
- Benevity Workplace Giving Program - If your employer participates, you can make donations to the DSF via payroll deduction.
- For those able to make a larger donation as corporate sponsors ($2000+), check out our corporate sponsors form
PyCoder’s Weekly
Issue #749: Polars vs SQL, Constants, deque, and More (2026-08-25)
Anarcat
A more nuanced view of LLMs
Also in this series:
After ranting and railing about LLMs or "AI" as the optimists (or accelerationists?) call it, I figured it might be important to be a little more honest about my use of LLMs and how I think about it more practically in the world.
The Debian vote context
This is not a coming out. I am not using LLMs on a daily basis, and this blog is, again, written out of my cold dead hands in a dying world, with over-engineered hardware and (to a certain extent, hi Emacs!) software, powered by 100% green energy built on stolen land.
There is a vote going on in Debian. If you're unfamiliar with it, you can catch up at LWN. So far I've essentially said "LLM is bad" which is not a very balanced or useful opinion. Obviously, people are using LLMs, sometimes unknowing or unwillingly, and we need to take that into account. Furthermore, there has been many different blog posts on Debian planet about this. Some that I found balanced, good summaries, even if I didn't fully agree with them, at least some did the basic civil service of being short. But others were just not only Wrong but also so long that I couldn't finish that I just had to write something.1
This is not an explanation of the ballots, nor how I will vote. This vote is Debian's failure of framing that debate in a reasonable way: we have 8 options on the ballot with many duplicates. We have failed to do the hard work of summarizing and aggregating options into a meaningful set. I doubt the final vote will represent a readable position we can rally around.
I have not read the two months of debates on the topic either. Normally, before voting, I take a cursory look at the debate to see points of view I might have missed. But in this case, it will just make me sad, add noise, and I'm already pretty sure on where I stand on this.
So let me describe how I use LLMs and how I think they fit in our work, as computer engineers and hobbyists.
My LLM use
Debian Packaging
An astute reader has pointed out that I maintain a package in Debian made to use Anthropic. It's actually multiple packages:
llm: a CLI utility and Python library for interacting with Large Language Models, with OpenAI as its default API backendllm-anthropic: a plugin forllmwhich allows me to talk to Anthropic's API instead of OpenAIanthropic-sdk-python: the SDKllm-anthropicrequires to do its work
As I previously explained in response, I am not entirely
comfortable with this work: it's a compromise. In fact, I first
uploaded llm to the contrib section of Debian, where we keep
software that depends on other non-free software, but I was told that,
since yt-dlp was in main, llm belonged there as well.
So I moved it to main, alongside similarly controversial tools
like llama.cpp or the python-openai library.
OpenAI and Anthropic usage
An important part of my work is technology watch. I keep tabs on thousands of (new and old) software projects, follow news, and generally try to keep my skills up to date. It's a pretty impossible race, especially as I grow older, but I still think I'm doing the right choices in my job.
Testing large language models is part of that work. At first, I was using ChatGPT's web interface, but it was annoying to copy-paste things into a browser, so I looked for different interfaces.
For a while I tried gptel, a "simple, extensible LLM client for
Emacs" but I found it kind of terrifying. Giving a LLM control over an
Emacs buffer seems like a security nightmare, so I stopped doing
that.
So I use the llm command-line tool to talk to Anthropic's API. I
started that in the summer of 2025, when I bought 20$USD of API
credits. Before that, I paid for a ChatGPT subscription and then
OpenAI credits, which expired and sent me over to Anthropic, which
seemed then to have better ethics.
As it turns out, Anthropic is also happy to work for the US military (which is a big red line for me). Anthropic also won't let you talk about the genocide in Gaza, it is destroying physical books, and is blackmailing us to use their product for security coverage.
Needless to say, Anthropic and "Claude" are not my friends, but they seem like the lesser evil in current "frontier models". So I have renewed, a couple of weeks ago, another 20$USD of API credits with Anthropic.
Actual prompts and responses
So what does 20$ give you at Anthropic anyways? What am I using LLMs for and how?
The neat thing with llm is that everything is logged in a sqlite
database, so there are some answers that are easy to get:
> llm logs status
Logging is ON for all prompts
Found log database at /home/anarcat/.config/io.datasette.llm/logs.db
Number of threads logged: 7
Number of turns logged: 12
Number of legacy conversations: 543
Number of legacy responses: 970
Database file size: 9.61MB
That is 10MB of logs, with about a thousand prompts.
My logs go back to 2024-03-07, a little over two years ago, and include a mix of Anthropic and OpenAI responses. I used it more in 2024 than 2025, and if the trend continues, I will have used it less in 2026 again:
> llm logs list -n 0 --json | jq -r .[].datetime_utc | sed 's/-.*//' | sort | uniq -c
527 2024
357 2025
98 2026
It looks like about 10 prompts per month right now, down from a peak of about 60 per month in 2024. It's pretty difficult to analyze those actual logs to get more patterns and I won't run the prompts through a model again to process them.
How I'm using models now
At first, I was using it partly for benchmarking model's capabilities, like Simon Willison does with his pelicans, clearly not trusting its output. But I was impressed by the capacities of the Claude Opus 4.5 model when it wrote this script in January. Impressed, but also scared: it's the first time I felt I could delegate the entirety of my programming to a model. Just run the code, if it works, it works, right?
So what do I use it now? As an example, here are the 10 last prompts in my history:
- there is now Claude 5, and a fable model, maybe you know about it?
- impress me
- not impressive, i already know all of this
- chat
- in postfix, i have a 300k mailing that happens regularly here. normally, it delivers within about...
- is there a way i could have drained the maildrop queue faster without removing the milter?
- the problem was that rspamd was timing out on the FUZZY_CALLBACK check. how do i disable that?
- how do i disable all spam checks? i just want rspamd to add dkim signatures
- how do the default_destination_concurrency_limit and initial_destination_concurrency settings int...
- mic check
The first one was me trying to confirm which model I am using, which
is not always obvious when going through the whole llm stack I've
been using. The following two are an attempt at seeing what the model
is capable of and I was "not impressed", to which Claude answered that
I have a "high bar", which, fair enough.
The chat is me failing to use a command line, which shows that
perhaps I need to readjust that "high bar", again.
The next five are a rather embarrassing debacle in a large Postfix
mailing that went sideways, and where I couldn't find an actual
Postfix expert of my level to help. The fabled Claude Fable 5 answered
rather correctly, but dangerously, that I could empty the queue by
disabling the non_smtpd_milters. What Fable (and myself) did not
realize is that the milter was also adding DKIM signatures, so while the
mailing was expedited, it was done without those precious signatures,
which got us promptly blocked at Gmail. We have recovered since, and,
thanks to the model and reading the Postfix manual for the
hundredth time, that pickup(8) is single-threaded and that we
needed to review the architecture of that mailing (and our spam
filters) a bit. Many tickets ensued.
The last one is a test I did to make sure my last uploads of
llm-anthropic and its dependency worked correctly.
Note that the above excludes 5 questions I asked Anthropic while writing this article, where I asked for synonyms and "what nanometer scale are arduino processors built from? how is an arduino CPU printed?", a question which Wikipedia furiously evades providing a good answer.
Those prompts are pretty typical of my LLM use: I'm testing the models to see if they work at all, but also, out of desperation, I fire off a prompt after I fire off questions to colleagues or search engines (in that order). It's often weird edge cases like the Prometheus query language, Python's matplotlib, LaTeX, Elisp, optimizations, and so on.
I use models for translation a lot. Being fully bilingual, it is common for me to think of a word in French or English and fail to find exactly the right word for that in the other language. Models help with that, and are also useful to find synonyms. Those are low-token uses that seem pretty innocuous to me, but I realize the irony of this after writing about the tower of Babel.
What I am not using models for
I am not using models to write prose.
I am not using models to read prose. If it's generated with LLMs, I stop reading.
I am not using models to write code, with the exception of that single Python script above.
I am generally not using models to review code, with exceptions. If
I get stuck on a hard problem, I might feed a piece of code to the
model. I repeatedly fed asncounter into Claude to try to fix a
performance regression I had introduced. It found micro-optimizations
that taught me a thing or two about Python's internal implementations,
but overall, it was mostly a waste of time. This was in June 2025, so
perhaps now models would fare better. I have not tried again.
I am not using LLMs to do Debian packaging. When I can, I manually review the diffs of packages I upload into Debian, still, by hand.
I do this for the reasons outlined in The Four Horsemen of the LLM Apocalypse, because I refuse to be complicit in the:
- aggressive and illegal scraping of the servers I steward
- world-wide computer hardware shortage (making it, by the way, nearly impossible to run presumably clean local models) and the attack on our job conditions (also discussed in The people vs the AI overlords)
- death of copyright and free software
- complication and enshifitication of everything, and the destruction of our communities
- the imperialist Nerd Reich that wants to take over the world
Like I reluctantly use Intel computers, I do fire off a prompt. But I still hold on to the dream that we can build communities of practice that hold human knowledge collectively and not offload that as a utility to some megalomaniac billionaire.
Their LLM use I am forced into
So that's me. Clearly, I'm going against the grain here. Everywhere I look, I see LLM-generated code and projects. Slop and botnets have flooded the web.
I use Wadamesh, clearly vibe-coded, because it's the best graphical interface for MeshCore that runs on portable devices. I wish it was made by a human, in a community I could participate in, but it isn't, and I don't.
I package the above llm toolset, which is more and more
vibe-coded, but I still review the diffs. And I have to say: I
trust Simon here. The code is verbose as hell, feels overengineered,
and llm feels slow, but it generally works, and Simon is still at
the gate.
The Anthropic SDK is another thing entirely. The 0.91.0 to 0.120 upload, for example, was nuts:
806 files changed, 72281 insertions(+), 1478 deletions(-)
I explicitly did not review that entire diff. It feels like there's a lot of garbage there to just have a shim between a proprietary API and Python. But this is the hand I've been dealt.
Larger projects LLM use
LLMs are being used in the Linux kernel, Firefox, rsync, Rust, and
other places. I don't feel good about this, particularly in Rust, but
they at least made a decent policy. I am glad GCC made a policy
against LLM contributions and I support the human Emacs
project.
We need to have a set of foundational tools that are "clean" in the sense that they are built upon a community of people that understand how they are built.
Maybe that's naive or even impossible. The Linux kernel and GCC, in particular, are massive projects that have long grown past the scale of a single person's understanding. But the theory was that a community of humans can understand collectively.
Now we seem to be throwing up our hands and giving up on that community. That LLMs will just fix the problem, whatever it is. But we're all just one rug pull away from being completely incapable of managing those projects. The argument there is that we'll just switch to local models, but no one is actually doing that. All I see is people use local models as a corner case (for privacy) or as in theory, but in reality, everyone uses the centralized frontier models right now. We just can't fallback.
We're in the same situation we were, a decade or two ago, when Microsoft decided it would kill free office alternatives by making Office free for non-profits. It worked: thousands, if not millions of schools, community groups and individuals stopped looking for alternatives (including free software but also "piracy") for Office and embraced what seemed like a generous offer.
Now Microsoft pulled the plug and Over 170,000 Nonprofits Lost All Their Data.
I'm afraid the rug pull on LLMs will be much worse: never mind that Linus won't be able to use his tireless helper to fix obscure kernel bugs; we're looking at a collapse of the economy so large that we are already talking about bailing out the companies responsible.
In a sense, the most striking thing about the Debian vote is it has actually no option to completely refuse upstream LLM contributions. It seems the community has taken it for granted that it's now impossible to build Debian entirely without LLMs. We lost the battle even without a fight, it seems.
A plea for small
If it has really become impossible for us to manage the complexity we have built, maybe it's time to stop and think about what we're doing in the first place. We're struggling to even bootstrap our current toolchain!
This is one of the things I like the most about working on the mesh: it's low tech, small Arduino devices that is built with decades-old semiconductor processes that is understandable by human beings.
Maybe the answer lies more in single-purpose devices like those communicators and simpler multi-purpose computers than what we have now, which is what the permacomputing movement is about.
Small is beautiful, let's scale it down.
- and yes, I'm sorry this has gotten this long, I hope you will forgive those 3000 words.↩
Ed Crewe
From Routing Checks to Trajectory Testing: Evaluating an Agentic Chatbot
Mike C. Fletcher
OpenGL Extrusions (and Tessellation)
I've released a new library opengl_extrusions which is a Numpy and Cython library that does 3D extrusions (like the GLE library) and tessellations (one of the things the GLU library does). The motivation being that the GLE library is constrained to compatibility contexts (think "legacy OpenGL"), so it doesn't work under modern core-profile contexts. The library has a very different API from GLE, but it does the same jobs, and has a conformance suite that verifies that it creates the same final shapes for a given input, albeit with a (hopefully cleaner) API. With the new API you get back a structure that looks exactly like what you use to construct a glTF object, arrays of points and index pointers.
Tessellation is handled with the CDT algorithm, which is not what GLU's tessellator uses. GLU is deprecated on some platforms (Mac), so we'll eventually need to move off it. This is just one piece of doing that, but it's a useful piece. CDT's biggest advantage is that it can avoid long spiky triangles that tend to cause rendering artefacts.
The library is entirely LLM coded, though I've tweaked docs here and there.
Python Software Foundation
Agata Skamruk: 2026 PSF Board Election Candidate Interview
Benjamin Manning: 2026 PSF Board Election Candidate Interview
Calvin Tsang: 2026 PSF Board Election Candidate Interview
Cecília Tivir: 2026 PSF Board Election Candidate Interview

