Planet Python
Last update: June 27, 2026 07:48 PM UTC
June 27, 2026
Go Deh
Sparse Ranges
June 26, 2026
Talk Python to Me
#553: All of our tools
This episode is a fun crossover from our Python news and tips podcast, Python Bytes. We have had some big changes over there. Brian Okken has moved on and Calvin Hendryx-Parker has joined the show as the new co-host. To kick off this new era, we decided to do a longer and more personal episode called "All Our Tools". The idea is both of us talk about some of our most useful day-to-day developer and business owner tools that we think you all would find useful. It was so well received, that I'm bringing it to you all as a crossover episode. Enjoy and we hope you find something new and awesome to help you with your software and data science day to day.
The No Title® Tech Blog
Just updated - Optimize Images v2.1.0
Optimize Images 2.1.0 brings native WebP support, a generalized format-conversion system, on-demand image inspection with EXIF reporting, and a new in-memory API for working with image bytes directly. It is a focused, fully backwards-compatible step forward for the command-line tool and its public API.
Bob Belderbos
There Is No Magic: An AI Agent in 60 Lines of Python
Everybody talks about agents, and a lot of people assume they're some new kind of model. They aren't. An agent is a small amount of plumbing around an LLM you already understand. Let's build one from scratch in Python and see exactly what that plumbing is.
June 25, 2026
Artem Golubin
Hexora v0.3: New features and improvements
Recently, I've improved my Python library, hexora. I wrote it to detect malicious Python code using static analysis.
In the new v.0.3.0 release, I've added new detections, and we now also use a simple machine learning model to analyze the whole file. The machine learning model uses code structure features, semantic features, and static code analysis to assess the entire Python file.
Although the model can detect malicious code without any detections coming from static analysis, its main use case is to filter false positives.
I've been testing it against newly published PyPI packages and it detects 2-10 new malicious packages each day.

Due to the number of published packages, before the machine learning model, I was getting around 5-10 false positives for 1[......]
Django Weblog
How the Django Software Foundation Became a CNA
Why the DSF pursued CNA status
Django has a long history of responsible security practices: a dedicated, private security mailing list, clear advisory policies, and predictable security releases. Even so, we relied on external organizations to assign CVE IDs (Common Vulnerabilities and Exposures). This sometimes introduced administrative delays and extra coordination overhead.
Becoming a CNA (CVE Numbering Authority) allows the DSF to:
- Assign CVEs ourselves for vulnerabilities in Django and selected community projects.
- Publish advisories more efficiently and in closer alignment with Django's established release workflow.
- Maintain strong independence in how Django handles security incidents.
The initial exploration
The process began with internal discussions within the DSF Board and Django Security Team. We evaluated:
- Whether our existing security process already met CNA expectations.
- Whether we had the organizational stability to take on long term responsibility for CVE assignment.
- The scope of projects we would cover.
- How to ensure we could meet the operational requirements without overloading volunteers and Django Fellows.
After confirming that our policies were mature and that the administrative workload would be manageable, we initiated the CNA application with MITRE.
Preparing the application
MITRE requires that new CNAs document their security processes and demonstrate that they can meet CNA obligations. Our preparation included:
-
Reviewing and updating the Django Security Policy.
-
Mapping our existing workflows to MITRE's CNA rules, including:
- How reports are received.
- How vulnerabilities are validated.
- How advisories are produced.
- How CVEs will be assigned and published.
-
Defining the scope of the CNA:
- Django itself as the core product.
- A small, clearly bounded set of related ecosystem projects.
-
Ensuring we had private communication channels and documented procedures for confidential handling.
-
Drafting the required procedural documentation for MITRE.
Most of the work here was not about creating new processes but about articulating long standing Django practices in the format MITRE expects.
Training and review
Once our initial documentation was accepted, MITRE scheduled us for CNA onboarding training. This covered:
- CNA rules and responsibilities.
- Required data fields for CVE Records.
- Expectations for coordination with reporters and downstream consumers.
- The publication workflow for CVE Records.
We also completed MITRE's required CNA onboarding exercises. As part of this process, we worked through sample security reports and demonstrated how we would determine CVE assignments, including cases where multiple CVEs may or may not be warranted for a single report.
Approval and onboarding
After MITRE approved our documentation, training, and exercise submissions, the DSF was formally granted CNA status. The announcements steps were:
- MITRE published our CNA scope on the official CNA directory.
- MITRE issued a press release.
- The DSF published a blog post announcing our new CNA status.
Lessons learned
A few procedural insights for other projects considering CNA status:
- If your project already has a mature and documented security process, becoming a CNA is mostly about formalizing what you already do.
- The documentation and validation steps take time. Most delays come from ensuring that all fields conform to the CVE schema. The whole process took about four months.
- The training is detailed and helpful. It clarifies exactly what CNAs are expected to produce and how CVE Records flow through the broader ecosystem.
- It is worth being explicit about scope early. Defining the boundary of responsibility reduces ambiguity later.
What changes for Django users
For most contributors and users, nothing changes. Django will continue to follow its established process for receiving reports, coordinating fixes, and publishing security releases.
The difference is that the DSF can now assign CVE IDs directly, which simplifies coordination and allows us to publish advisories with fewer external dependencies.
Acknowledgments
This work was led by Django Fellows Natalia Bidart and Jacob Walls, with support from the Django Security Team and the DSF Board. We are grateful to MITRE for their guidance during the onboarding process.
If you have questions about Django's CNA scope or security process, contact the Django Security Team.
PyCharm
Explicit Lazy Imports Are Coming to Python 3.15
A while ago at PyCon US 2026, I had the pleasure of listening to the Python Steering Council give updates about new features that are being added in Python 3.15. One that stood out was explicit lazy imports (via PEP 810), which defer module loading until first use. I am curious to see how this […]
Bob Belderbos
Python Is Not Enough: Why Pythonistas Love Rust (Podcast)
I joined Bas Steins and Michal Martinka on their complexity.fm show to talk about why Pythonistas are picking up Rust, what AI really does to how we learn, and why vibe coding is a myth. The conversation ran for over an hour because there was a lot to unpack.
June 24, 2026
Brett Cannon
Why I wrote PEP 832 -- virtual environment discovery
While I decide what to do with PEP 832 after polling folks on their opinion, I thought I would write out why I&aposm even bothering with any of this.
I&aposm going to talk from the perspective of VS Code and its Python extensions, but you could
Django Weblog
Django 6.1 beta 1 released
Django 6.1 beta 1 is now available. It represents the second stage in the 6.1 release cycle and is an opportunity to try out the changes coming in Django 6.1.
Django 6.1 offers a harmonious mélange of new features and usability improvements, which you can read about in the in-development 6.1 release notes.
Only bugs in new features and regressions from earlier Django versions will be fixed between now and the 6.1 final release. Translations will be updated following the "string freeze", which occurs when the release candidate is issued. The current release schedule calls for a release candidate in about a month, with the final release scheduled roughly two weeks later on August 5.
Early and frequent testing from the community will help minimize the number of bugs in the release. Updates on the release schedule are available on the Django forum.
As with all alpha and beta packages, this release is not for production use. However, if you'd like to try some of the new features or help find and fix bugs (which should be reported to the issue tracker), you can grab a copy of the beta package from our downloads page or on PyPI.
The PGP key ID used for this release is Jacob Walls: 131403F4D16D8DC7
death and gravity
reader 3.26 released – discovery, exports, demo
Spyder IDE
How your donations transformed Spyder in 2025
Thanks to the community's financial support, Spyder has not only survived but thrived in 2025. Read on as we share the new features, releases and interface improvements from the last year that your donations directly made possible.
June 23, 2026
PyCoder’s Weekly
Issue #740: Pluggy, ABCs, Scrapy Extensions, and More (2026-06-23)
Glyph Lefkowitz
Adversarial Communication
“AI” turns every conversation into a fight, because fighting is what they are good at.
Python Software Foundation
Mitigated API authentication bypass for python.org download metadata
Python Bytes
#485 Creating memories
Topics include Backup Docker volumes locally or to any S3, Pyodide 314.0 Release, nb-cli, and Hindsight.
Python Insider
Mitigated API authentication bypass for python.org download metadata
Vulnerability mitigated in python.org with follow-up third-party audit from Trail of Bits
Python 3.15.0 beta 3 is here!
The penultimate 3.15 beta is out!
Armin Ronacher
The Coming Loop
June 22, 2026
Rodrigo Girão Serrão
Write a coding agent from first principles
Learn how to write a coding agent in this Python tutorial that teaches how to interact with an LLM through an API, how to manage the conversation context, and how to do tool calling.
Introduction
This tutorial will show you how to create your own coding agent from first principles. By doing so, you'll understand how coding agents work under the hood.
Prerequisites
To be able to follow this tutorial, you'll need
- prior Python experience: this tutorial is not suitable for people who don't have programming experience
- a valid Claude API key: you can get a Claude API key in the Claude Console dashboard[^1]
- uv: to manage the project you'll be working on
The concepts explained in this tutorial are independent from your LLM provider but the code snippets will make use of the Claude API and its Python SDK. This means that you can follow along with a different model provider as long as you adapt the code snippets to match the format expected by the API of your provider.
What's a coding agent?
A coding agent is an agent that's specialised for coding. In turn, an agent is just an LLM that has been extended with extra functionality that allows it to interact with its environment. This extra functionality is provided through tools, one of the core ideas covered in this tutorial.
This short definition still hides a lot of details, but instead of giving you a theoretical definition you can learn what a coding agent is by creating one. That starts now.
Project set up
To set your project up, start by using uv to create a packageable app project[^2]:
% uv init --app --package agent
Initialized project `agent` at `/Users/rodrigogs/Documents/mathspp/agent`
Then, cd into the project and add the two dependencies you'll need:
% cd agent
% uv add python-dotenv anthropic
You'll use python-dotenv to help you with authentication to access the Claude API and you'll use the dependency anthropic to make it easier to interact with the Claude API.
To set up authentication, create a .env file and paste your Claude API key there in front of the variable ANTHROPIC_API_KEY.
When you're done, your .env file should look like this:
ANTHROPIC_API_KEY="sk-ant-api03-qI_3mJ..."
To make sure you never upload your API key to GitHub by accident, add the file .env to your .gitignore:
# .gitignore
# ... other entries generated by uv
.env
Now that you've set up your project, you can make your first request to the Claude API.
Interacting with an LLM
A coding agent needs an LLM at its core.
Your LLM can come from any provider you want but you're going to use Claude because its SDK (the dependency anthropic you added in the previous section) is easy to use and because Claude is a popular model provider.
Using the anthropic SDK, here's how you can send a message to the LLM:
# src/agent/__init__.py
from anthropic import Anthropic
import dotenv
dotenv.load_dotenv() # Load .env
MODEL = "claude-haiku-4-5"...
June 21, 2026
The Python Coding Stack
2. Anatomy of an Agent
Authors: Priya & Stephen
Christian Ledermann
Stop Copy-Pasting Your .pre-commit-config.yaml
Stop Copy-Pasting: Introducing pc-init
We’ve all been there: you’re starting a new project, you’ve got your repo initialized, and now comes the tedious part—setting up the quality gates.
You know you need pre-commit (or the newer prek) to keep your code clean, but you end up hunting through your older repositories to find the "best" .pre-commit-config.yaml to copy and paste. Then, you spend ten minutes editing paths, versions, and configurations to match the specific needs of your new stack.
It’s a chore that breaks your flow before you’ve even written a line of code. That is exactly why I built pc-init.
The Problem: The "Config Archeology" Workflow
Most languages and frameworks have a gold standard for quality tools. If you're working in Python, you want ty and ruff; in React, you want eslint and prettier.
Manually setting these up requires:
- Identifying the recommended tools for your specific stack.
- Looking up the correct hook repository URLs, revisions, and arguments.
- Writing the YAML by hand (and hoping you didn't miss a syntax error).
Doing this every other month is just frequent enough to be a persistent pain point, but not frequent enough to have the workflow committed to muscle memory.
The Solution: pc-init
pc-init is a CLI tool designed to replace "config archeology" with a single, declarative command. It scaffolds a production-ready .pre-commit-config.yaml based on your project's technology stack.
Instead of copying old files, you simply tell pc-init what you're building, and it builds the configuration for you.
How it works
pc-init uses a system of language and framework presets. You provide the parameters, and it handles the rest:
# For a standard Python project
pc-init --lang py
# For a JavaScript project using React
pc-init --lang js --framework react
# For a Python project using Django
pc-init --lang py --framework django --force
Why use pc-init?
- Zero Boilerplate: No more hunting for URLs or managing complex YAML structures.
- Standardization: It ensures consistency across all your projects by enforcing the same quality standards.
-
Extensible: Not happy with the default presets? You can point
--presetsto your own local directory or a private git repository to share your team's custom standards across your entire organization. - Flexible: It works seamlessly with both pre-commit and prek.
Get Started
If you’re ready to speed up your setup process, you can install pc-init via uv:
uv tool install pc-init
After generating your config, don't forget to run pre-commit autoupdate or prek autoupdate to ensure you are pulling the very latest versions of your selected tools.
If you have suggestions for new presets or run into issues, please head over to the GitHub repository and open an issue. Let’s make boilerplate setup a thing of the past.
Bob Belderbos
From Python to Rust: Master Iterators by Rebuilding 10 Unix Tools
The fastest way I know to learn a language is to rebuild something you already understand. You stop fighting the problem and spend your attention on the syntax and the idioms. That is the whole idea behind the new Unix tools track I just released on the Rust platform: ten small command-line classics, each one a pure function you implement and cargo test to validate you got it right.
June 20, 2026
Bob Belderbos
Profile First: A 10x Faster Django Test Suite
The Rust Platform Django test suite took 30 seconds to run. I had a hunch it was database-related. Of course I was wrong. I profiled it with cProfile and cut it from 30 to 3 seconds.
June 19, 2026
Core Dispatch
Core Dispatch #6
Welcome back to Core Dispatch! This edition covers June 4 through 19, 2026. Python 3.14.6 and 3.13.14 landed on June 10, and the next milestone is 3.15.0 beta 3 on June 23. The big news this fortnight comes from the Steering Council, who put out an [announcement on the path forward for the experim
