skip to navigation
skip to content

Planet Python

Last update: June 06, 2026 04:44 PM UTC

June 06, 2026


Armin Ronacher

Communities of Not

June 06, 2026 12:00 AM UTC

June 05, 2026


Will Kahn-Greene

Bleach 6.4.0 releases -- final release

What is it?

Bleach is a Python library for sanitizing and linkifying text from untrusted sources for safe usage in HTML.

Bleach v6.4.0 released!

Bleach 6.4.0 includes two security fixes, a fix to tinycss2 dependency requirements, and some other things.

See the changes here:

https://bleach.readthedocs.io/en/latest/changes.html#version-6-4-0-june-5th-2026

Bleach v6.4.0 is the final release

I haven't used Bleach on a project in years, but I still had some time to maintain it. That changed about a year ago when I got re-orged into a new role and I haven't had time to do any Bleach work since then.

To recap, Bleach sits on top of html5lib which hasn't been actively maintained in years. It is dangerous to maintain Bleach in that context.

We vendored html5lib so we could make adjustments to the library to keep Bleach going. This is not a sustainable approach, but it was ok for the short term.

Over the years, we've talked about other options:

  1. find another library to switch to

  2. take over html5lib development

  3. fork html5lib and vendor and maintain our fork

  4. write a new HTML parser

  5. etc

None of those are feasible for me.

Bleach has been a solo-maintained project for a while now. The world is crazy and it's much harder to build a team of trusted maintainers now than it was (or at least, it sure feels that way). I don't see any possibility of increasing the maintenance team or passing it to someone else responsibly.

Switching contexts from my regular work to Bleach is really hard. Bleach is complicated, the problem domain is complicated, and there's a lot of nuanced context. I can't just switch gears, spend 15 minutes on Bleach to do something, and then switch back to the rest of my day. I periodically get nag messages about this which are entirely valid, but there's nothing I can do about it. It doesn't feel great.

Then in 2025, Emil, a long-time Bleach contributor, built justhtml which gives us an easy migration path off of Bleach. He even took the time to write a migration guide.

Thoughts and statistics

In 2019, when I stepped down the first time, I wrote a post on stepping down.

In 2023, when I deprecated the project, I wrote a post on Bleach 6.0.0 and deprecation.

It feels weird to end a project that's outlived many of the Mozilla sites and Python web frameworks it was designed to protect.

What happens now?

This is the end of the project.

/images/bleach_deprecation.thumbnail.jpg

Bleach. Last release.

If you're still using Bleach, I think you have three options:

  1. End your project. Maybe you don't need to be maintaining your thing anymore? Use Bleach as your reason to exit and do something different with your time on Earth.

  2. Switch to the sanitizer API. Rework your project to use the sanitizer API.

  3. Swap Bleach out for justhtml. Emil provided a migration guide for switching from Bleach to justhtml.

Good luck with whatever option you choose!

Thanks!

Many thanks to James who created Bleach and gave it a set of first principles that guided our choices for 16 years.

Many thanks to Greg who I worked with on Bleach for a long while and maintained Bleach for several years. Working with Greg was always easy and his reviews were thoughtful and spot-on.

Many thanks to Emil who was a contributor to Bleach for a long while and created justhtml providing Bleach users a migration path.

Many thanks to Jonathan who, over the years, provided a lot of insight into how best to solve some of Bleach's more squirrely problems.

Many thanks to Sam who was an indispensible resource on HTML parsing and sanitizing text in the context of HTML.

Many thanks to all the users and contributors of Bleach!

Where to go for more

For more specifics on this release, see here: https://bleach.readthedocs.io/en/latest/changes.html#version-6-4-0-june-5th-2026

Documentation and quickstart here: https://bleach.readthedocs.io/en/latest/

Source code and issue tracker here: https://github.com/mozilla/bleach/

June 05, 2026 01:00 PM UTC


Real Python

The Real Python Podcast – Episode #298: Reducing the Size of Python Docker Containers

How can you easily reduce the size of a Python Docker container? What are the exceptions you should catch in your code? Christopher Trudeau is back on the show this week with another batch of PyCoder's Weekly articles and projects.

June 05, 2026 12:00 PM UTC


EuroPython Society

EuroPython Society at PyCon US 2026

This year we were back at PyCon US, and this time in sunny Long Beach, California.

We had a booth again, which has quickly become one of our favourite parts of the trip. It&aposs such a great chance to meet folks from other Python communities, catch up with

June 05, 2026 09:28 AM UTC


Bob Belderbos

How to Update Multiple Page Elements from One htmx Request

A button submits code, tests run, feedback appears. Standard htmx. But the submissions dropdown stays stale; the new submission is in the database, just not in the dropdown. One request, two elements to update.

June 05, 2026 12:00 AM UTC


Seth Michael Larson

Is the Super Smash Bros. Brawl donut from Mister Donut?

June 05, 2026 12:00 AM UTC

June 04, 2026


Kay Hayen

Nuitka Release 4.1

This is to inform you about the new stable release of Nuitka. It is the extremely compatible Python compiler, “download now”.

June 04, 2026 10:00 PM UTC


The Python Coding Stack

Down The Iterator Rabbit Hole

Following the trail when you have a chain of iterators

June 04, 2026 12:50 PM UTC


Real Python

Quiz: How to Read User Input From the Keyboard in Python

Try your hand at reading Python keyboard input with input(), handling errors, hiding passwords, and validating with PyInputPlus.

June 04, 2026 12:00 PM UTC


Python Software Foundation

PSF Strategic Plan 2026 Draft: Open for Community Feedback

June 04, 2026 09:38 AM UTC


Adrarsh Divakaran

Building AI Agents in Python

June 04, 2026 06:50 AM UTC


Core Dispatch

Core Dispatch #5

Welcome back to Core Dispatch! This edition covers May 18 through June 4, 2026. As promised, Python 3.15.0 beta 2 landed on June 2. Two more milestones are close behind: 3.13.14 and 3.14.6 on June 9, followed by 3.15.0 beta 3 on June 23. There's also a healthy batch of changes landing for 3.15: an

June 04, 2026 12:00 AM UTC


PyCon Ireland

CFP Deadline Moved to 31 July 2026

The PyCon Ireland 2026 Call for Proposals now closes on 31 July 2026. Here is why we brought the deadline forward and what it means for you.

June 04, 2026 12:00 AM UTC


Bob Belderbos

"Rust Is for People Who Want to Be Punished." Now Jochen Trusts It More Than Python.

Jochen Deister is a lawyer who codes for fun. He has years of Python behind him and no intention of ever being hired to program.

Three months ago, Rust was just a name to him, the language for "the big shots" with a notoriously steep learning curve. Then he built a JSON parser from scratch in Rust, and it ran faster than the equivalent in Python on every dataset he tested, up to 3.5x faster on some. "Holy F" he reacted when he saw the results.

June 04, 2026 12:00 AM UTC

June 03, 2026


Real Python

How to Use GitHub Copilot Code Review in Pull Requests

Learn how to use GitHub Copilot code review on pull requests for AI-assisted feedback, one-click fixes, and project-specific custom instructions.

June 03, 2026 02:00 PM UTC

Quiz: How to Use GitHub Copilot Code Review in Pull Requests

Test your knowledge of GitHub Copilot code review in pull requests, including custom instructions and automatic reviews.

June 03, 2026 12:00 PM UTC


Django Weblog

Django security releases issued: 6.0.6 and 5.2.15

In accordance with our security release policy, the Django team is issuing releases for Django 6.0.6 and Django 5.2.15. These releases address the security issues detailed below. We encourage all users of Django to upgrade as soon as possible.

get_signed_cookie() derived the signing salt by concatenating the cookie name (key) and salt arguments. When distinct name and salt pairs produced the same concatenation, cookies could be accepted in a context different from the one where they were signed.

Cookies are now signed with an unambiguous salt derivation. For backwards compatibility, cookies signed by older Django versions are accepted until Django 7.0.

This issue has severity "low" according to the Django security policy.

Thanks to Peng Zhou for the report.

CVE-2026-7666: Potential unencrypted email transmission via STARTTLS in the SMTP backend

When using EMAIL_USE_TLS, a failed STARTTLS handshake could leave a partially-initialized connection that would subsequently be reused for sending email without encryption. This can occur with fail_silently=True, as used by send_mail() and BrokenLinkEmailsMiddleware, among others. Connections configured with EMAIL_USE_SSL are not affected.

This issue has severity "low" according to the Django security policy.

Thanks to Kasper Dupont for the report.

CVE-2026-8404: Potential exposure of private data via case-sensitive Cache-Control directives in UpdateCacheMiddleware

django.middleware.cache.UpdateCacheMiddleware and django.views.decorators.cache.cache_page decorator incorrectly cached responses marked with private Cache-Control directives when using mixed or uppercase values (e.g. Private).

The django.views.decorators.cache.cache_control decorator and django.utils.cache.patch_cache_control() function were not affected, since they normalize directives to lowercase. This issue only affects responses where Cache-Control is set manually.

This issue has severity "low" according to the Django security policy.

Thanks to Ahmed Badawe for the report.

CVE-2026-35193: Potential exposure of private data via missing Vary: Authorization in UpdateCacheMiddleware

django.middleware.cache.UpdateCacheMiddleware and django.views.decorators.cache.cache_page decorator allowed responses to requests bearing an Authorization header (and without Cache-Control: public) to be cached. To conform with the existing mechanism for constructing cache keys, responses to these requests will now vary on Authorization.

This issue has severity "low" according to the Django security policy.

Thanks to Shai Berger for the report.

CVE-2026-48587: Potential exposure of private data via whitespace padding in Vary header

django.middleware.cache.UpdateCacheMiddleware incorrectly cached responses whose Vary header values contained leading or trailing whitespace. Because has_vary_header() failed to strip that whitespace, a response with a Vary: * header (note the trailing space) was not recognized as containing the wildcard, causing it to be stored and potentially served from the cache when it should not have been.

This issue has severity "low" according to the Django security policy.

Thanks to Navid Rezazadeh for the report.

Affected supported versions

Resolution

Patches to resolve the issue have been applied to Django's main, 6.1 (currently at alpha status), 6.0, and 5.2 branches. The patches may be obtained from the following changesets.

CVE-2026-7666: Potential unencrypted email transmission via STARTTLS in the SMTP backend

CVE-2026-8404: Potential exposure of private data via case-sensitive Cache-Control directives in UpdateCacheMiddleware

CVE-2026-35193: Potential exposure of private data via missing Vary: Authorization in UpdateCacheMiddleware

CVE-2026-48587: Potential exposure of private data via whitespace padding in Vary header

The following releases have been issued

The PGP key ID used for this release is Natalia Bidart: 2EE82A8D9470983E

General notes regarding security reporting

As always, we ask that potential security issues be reported via private email to security@djangoproject.com, and not via Django's Trac instance, nor via the Django Forum. Please see our security policies for further information.

June 03, 2026 11:00 AM UTC


Python GUIs

Authentication and Authorization with PyQt6 or PySide6 — Secure your desktop applications with login flows, token-based auth, and role-based access control

How can I add authentication and authorization to a PyQt6 application? Is there something built into Qt to make this easier?

June 03, 2026 06:00 AM UTC


Bob Belderbos

How to Tell if Your Python Mock Is Actually Working

A test can pass for the wrong reason. When you're mocking a third-party API call, the test might look green because the real API happened to return an error, not because your mock did anything at all.

June 03, 2026 12:00 AM UTC

June 02, 2026


PyCoder’s Weekly

Issue #737: Polars 1.41, Email, Great Docs, and More (2026-06-02)

June 02, 2026 07:30 PM UTC


Real Python

Structuring Your Python Script

Master Python script structure with best practices for shebangs, ordered imports, formatting with Ruff, constants, and a clean entry point.

June 02, 2026 02:00 PM UTC


PyCharm

Top Agentic Frameworks for Building Applications 2026

In 2026, the world of AI is changing at a serious pace. The days of AI systems dealing solely in single-prompt interactions are coming to an end. Instead, these models are evolving into agentic systems – long-running, goal-driven software enabled by agentic frameworks that are becoming a critical layer in modern application architecture. This rapid […]

June 02, 2026 12:12 PM UTC


Real Python

Quiz: Python's Format Mini-Language for Tidy Strings

Test your understanding of Python's format mini-language and how to use format specifiers to align text, control precision, and tidy your strings.

June 02, 2026 12:00 PM UTC

Quiz: Structuring Your Python Script

Check your understanding of Python script structure, including shebangs, import order, ruff formatting, constants, and a clean entry point.

June 02, 2026 12:00 PM UTC


Python Software Foundation

No Starch Press Humble Bundle: Grab a Deal and Support the PSF!

June 02, 2026 07:21 AM UTC