Planet Python
Last update: January 09, 2026 04:46 AM UTC
January 08, 2026
Rodrigo Girão Serrão
Recursive structural pattern matching
Learn how to use structural pattern matching (the match statement) to work recursively through tree-like structures.
In this short article you will learn to use structural pattern matching in recursive, tree-like data structures.
The examples from this article are taken from a couple of recent issues of my weekly newsletter.
A recursive data structure
Structural pattern matching excels at... matching the structure of your objects! For the two examples in this article, we'll be using a number of dataclasses that you can use to build abstract Boolean expressions:
from dataclasses import dataclass
class Expr:
pass
@dataclass
class And(Expr):
exprs: list[Expr]
@dataclass
class Or(Expr):
exprs: list[Expr]
@dataclass
class Not(Expr):
expr: Expr
@dataclass
class Var(Expr):
name: str
For example, the code Not(And([Var("A"), Var("B")])) represents the Boolean expression not (A and B).
Evaluating a Boolean expression
Suppose you have a Boolean expression built out of the components shared above. How do you evaluate that formula if you are given the assignments that map the variables to their values?
For example, if you have the assignments {"A": True, "B": False} (for example, a dictionary that maps variable names to values), how can you determine that the expression Not(And([Var("A"), Var("B")])) is True?
This is where structural pattern matching can be applied recursively and it's where it really shines!
To solve this problem, you will write a function called evaluate(expression: Expr, assignments: dict[str, bool]) -> bool.
Your function accepts an expression and the assignments in the form of a dictionary and it returns the final Boolean value the expression evaluates to.
Since you're accepting an expression, you're going to use the match statement on the full expression and then create a case branch for each of the possible expressions you might have:
- a variable;
- an
Andexpression; - an
Orexpression; or - a
Notexpression.
The structure of the code looks like this:
def evaluate(expression: Expr, assignments: dict[str, bool]) -> bool:
match expression:
case Var(): pass
case And(): pass
case Or(): pass
case Not(): pass
The trick here is realising that you're using Expr as the type of the argument but really, you always expect the argument to be an instance of one of the subclasses of Expr, and not a direct Expr instance.
However, to make sure you don't trip on a weird bug later on, and because this matching is supposed to be exhaustive – you're supposed to have one case for each subclass of Expr – you can defend yourself by including a catch-all pattern that raises an error.
When I'm being lazy, I just raise a RuntimeError:
def evaluate(expression: Expr, assignments: dict[str, bool]) -> bool:
match expression:
case Var(): pass
case And(): pass
case Or(): pass
case Not(): pass
case _:
raise RuntimeError(
f"Couldn't evaluate expression of type {type(expression)}."
)
Now, it's just a matter of implementing the evaluation logic. In the case of a variable, all you have to do is fetch the variable value from the corresponding dictionary. However, to make it more convenient to...
Stéphane Wirtel
Automating TLS Certificate Monitoring with GitHub Actions, certificate_watcher, and Slack
Introduction
As a consultant constantly working with clients, I found myself in a familiar predicament: my head was always down, focused on delivering value to customers, but my own infrastructure monitoring was non-existent. I had no simple way to track SSL/TLS certificate expirations across the multiple domains I managed - personal sites, client projects, and community services.
I needed a solution, but I had several constraints:
- No time for complex setup: I couldn’t afford to spend days installing, configuring, and deploying yet another monitoring service
- Easy maintenance: Whatever I built had to be low-maintenance - I didn’t want another system to babysit
- Transparency and control: I wanted a simple text file in Git listing the hosts to monitor, so I could see exactly what was being checked and track changes over time
- Zero infrastructure: No servers to provision, patch, or pay for
Around this time, a friend named Julien shared his project called certificate_watcher, a lightweight Python tool for checking SSL certificate expiration. I contributed a few patches (if memory serves), and it clicked: what if I could combine this with GitHub Actions and Slack notifications?
January 07, 2026
Real Python
How to Build a Personal Python Learning Roadmap
Learn how to create a personalized Python learning roadmap. Set goals, choose resources, and build a plan to track your progress and stay motivated.
Stéphane Wirtel
dsmtpd 1.2.0: Test Your Emails Risk-Free
The Test Email That Never Should Have Been Sent
You know that feeling? You’re developing a new email feature, you run your test script, and boom — you realize 3 seconds too late that you used the production database. Your CEO just received an email with the subject “TEST - DO NOT READ - LOREM IPSUM”.
Or worse: you configured a cloud SMTP server for testing, forgot to disable actual sending, and now your Mailgun account is suspended for “suspicious activity” because you sent 847 emails to test@example.com in 5 minutes.
Python⇒Speed
Unit testing your code's performance, part 1: Big-O scaling
January 06, 2026
PyCoder’s Weekly
Issue #716: Performance Numbers, async Web Apps, uv Speed, and More (Jan. 6, 2026)
Django Weblog
Django bugfix releases issued: 5.2.10, 6.0.1
Today we've issued the 5.2.10 and 6.0.1 bugfix releases.
The release packages and checksums are available from our downloads page, as well as from the Python Package Index.
The PGP key ID used for these releases is Jacob Walls: 131403F4D16D8DC7
Real Python
Tips for Using the AI Coding Editor Cursor
Learn Cursor fast: AI-powered coding with agents, project-aware chat, inline edits, and VS Code workflow -- ship smarter, sooner.
Seth Michael Larson
“Food JPEGs” in Super Smash Bros & Kirby Air Riders
January 05, 2026
PyCharm
The next edit suggestions feature is now enabled in all JetBrains IDEs for JetBrains AI Pro, AI Ultimate, and AI Enterprise subscribers. Yes, you read that right! JetBrains-native diff suggestions are available right in your editor. Global support for optimized latency. Out-of-the-box IDE actions for reliability. And the best part? It doesn’t consume your AI […]
Real Python
Learn From 2025's Most Popular Python Tutorials and Courses
Pick from the best Python tutorials and courses of 2025. Revisit core skills, 3.14 updates, AI coding tools, and project walkthroughs. Kickstart your 2026!
Quiz: How to Convert Bytes to Strings in Python
Decode bytes into readable strings in Python. Test your skills working with data from files, APIs, and databases.
Quiz: How to Properly Indent Python Code
Practice proper Python indentation. Take a quiz on using spaces, editor settings, and autoformatting correctly.
Patrick Müller
Static Protocols in Python: Behaviour Over Inheritance
The first time I read about protocols was in the book "Fluent Python" by Luciano Ramalho. This book goes deep. Deeper than I knew Python at that time. If you hadn&apost heard of Protocols before, I&aposll give you a short introduction.
Protocols have something
Talk Python to Me
#533: Web Frameworks in Prod by Their Creators
Today on Talk Python, the creators behind FastAPI, Flask, Django, Quart, and Litestar get practical about running apps based on their framework in production. Deployment patterns, async gotchas, servers, scaling, and the stuff you only learn at 2 a.m. when the pager goes off. For Django, we have Carlton Gibson and Jeff Triplet. For Flask, we have David Lord and Phil Jones, and on team Litestar we have Janek Nouvertné and Cody Fincher, and finally Sebastián Ramírez from FastAPI is here. Let’s jump in.
Python Bytes
#464 Malicious Package? No Build For You!
Topics include ty: An extremely fast Python type checker and LSP, Python Supply Chain Security Made Easy, typing_extensions, and MI6 chief: We'll be as fluent in Python as we are in Russian.
Glyph Lefkowitz
How To Argue With Me About AI, If You Must
If you insist we have a conversation, please come prepared.
Zato Blog
Python scheduler for API integrations
Python scheduler for API integrations
Are you looking for a practical way to automate API tasks with reliable scheduling? This tutorial demonstrates how to implement task scheduling using Zato within Docker.
The guide focuses on real-world implementation rather than theory, showing you how to build scheduling solutions that work consistently in production environments.
What you'll learn in the tutorial:
- How to set up a Python scheduler with Docker
- Creating services that run on precise intervals (as short as 5 seconds)
- Techniques for API automation, SQL database integration, and Bash script execution
- DevOps practices for maintaining scheduled jobs across environments
More resources
➤ Python API integration tutorials
➤ What is an integration platform?
➤ Python Integration platform as a Service (iPaaS)
➤ What is an Enterprise Service Bus (ESB)? What is SOA?
➤ Open-source iPaaS in Python
➤ What is a Network Packet Broker? How to automate networks in Python?
January 04, 2026
Python Morsels
Debugging with f-strings
If you're debugging Python code with print calls, consider using f-strings with self-documenting expressions to make your debugging a little bit easier.
A broken Python program
Here we have a program that makes a random math prompt and then validates whether the answer give by the user is correct:
import random
x = random.randrange(1, 10)
y = random.randrange(1, 10)
answer = input(f"What's {x} multiplied by {y}? ")
expected = x * y
if answer == expected:
print("Correct!")
else:
print("That's incorrect")
This program doesn't work right now:
$ python3 check_mult.py
What's 9 multiplied by 8? 72
That's incorrect
Our program always tells us that our answer is incorrect.
Troubleshooting with print
Now, we could try to …
Read the full article: https://www.pythonmorsels.com/debugging-with-f-strings/
Artem Golubin
Recent optimizations in Python's Reference Counting
It's been a while since I've written about CPython internals and its optimizations. My last article on garbage collection was written 8 years ago.
A lot of small optimizations were added since then. In this article, I will highlight a new optimization for reference counting that uses a static lifetime analysis.
Background on reference counting in CPython
Reference counting is the primary memory management technique used in CPython.
In short, every Python object (the actual value behind a variable) has a reference counter field that tracks how many references point to it. When an object's reference count drops to zero, the memory occupied by that object is immediately deallocated.
For hot loops, this can lead to significant overhead due to the frequent incrementing and decrementing of reference counts.[....]
EuroPython
Humans of EuroPython: Marina Moro López
EuroPython wouldn’t exist if it weren’t for all the volunteers who put in countless hours to organize it. Whether it’s contracting the venue, selecting and confirming talks & workshops or coordinating with speakers, hundreds of hours of loving work have been put into making
January 03, 2026
Hugo van Kemenade
Localising xkcd
I gave a lightning talk at a bunch of conferences in 2025 about some of the exciting new things coming in Python 3.14, including template strings.
One thing we can use t-strings for is to prevent SQL injection. The user gives you an untrusted t-string, and you can sanitise it, before using it in a safer way.
I illustrated this with xkcd 327, titled “Exploits of a Mom”, but commonly known as “Little Bobby Tables”.
I localised most of the slides for the PyCon I was at, including this comic. Here they are!
PyCon Italia #
May, Bologna
PyCon Greece #
August, Athens
PyCon Estonia #
October, Tallinn
PyCon Finland #
October, Jyväskylä
PyCon Sweden #
October, Stockholm
Thanks #
Thanks to Randall Munroe for licensing the comic under the Creative Commons Attribution-NonCommercial 2.5 License. These adaptations are therefore licensed the same way.
Finally, here’s links for 2026, I recommend them all:
- PyCon Italia, 27-30 May: the CFP is open until 6th January
- PyCon Estonia, 8-9 October
- PyCon Greece, 12-13 October
- PyCon Sweden, TBA
- PyCon Finland, TBA
January 02, 2026
Real Python
The Real Python Podcast – Episode #278: PyCoder's Weekly 2025 Top Articles & Hidden Gems
PyCoder's Weekly included over 1,500 links to articles, blog posts, tutorials, and projects in 2025. Christopher Trudeau is back on the show this week to help wrap up everything by sharing some highlights and uncovering a few hidden gems from the pile.
Glyph Lefkowitz
The Next Thing Will Not Be Big
Disruption, too, will be disrupted.
Seth Michael Larson
New ROM dumping tool for SNES & Super Famicom from Epilogue

